一,數據庫事務的定義
總得來說,事務是為了保證數據的安全性,一致性,正確性。必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性
1. 原子性(atomic),事務必須是原子工作單元;對於其數據修改,要么全都執行,要么全都不執行
2. 一致性(consistent),事務的執行結果,必須是從一個一致狀態,變成另一個新的一致狀態。事務的原子性保證其一致性
3. 隔離性(insulation),主要在並發時,各個事務之間互不影響。並發事務所作的修改必須與任何其它並發事務所作的修改隔離。
4. 持久性(Duration),事務一旦提交,數據就永久的保存在數據庫,它對於系統的影響是永久性的。
二,並發帶來的數據安全問題。
1 臟讀:一個事務讀取到另一個事務未提交的數據,顯然該未提交事務可能發生錯誤而回滾沒有保存進數據庫,那么讀到的數據就是錯誤的數據。
2.第一類更新丟失:開啟一個事務,讀取到一行數據,另一個事務也讀到同一行數據。后一個事務提交事務保存到數據庫后第一個事務更新時發生異常而回滾導致后一個事務的更新丟失
3 第二類更新丟失:一個事務從數據庫得到一行數據保存在內存中,這時另一個事務開發也讀到同一行一樣的數據,另一個事務更改了事務並提交保存到數據庫。這時第一個事務依然是最開始的數據(沒有重新去數據庫讀取)進行修改提交導致另一個事務提交的信息丟失。
4 不可重復讀:一個事務兩次讀取同一行數據,結果得到不同狀態結果,如中間正好另一個事務更新了該數據,兩次結果相異,不可信任。
5 幻讀: A事務讀取B事務提交的新增數據,這時A事務將出現幻象讀的問題
注:幻象讀和不可重復讀是 兩個容易混淆的概念,前者是指讀到了其它已經提交事務的新增數據,而后者是指讀到了已經提交事務的更改數據(更改或刪除)
三、數據庫事務隔離級別
為了解決數據庫事務並發運行時的各種問題數據庫系統提供四種事務隔離級別:
1. Serializable 串行化
2. Repeatable Read 可重復讀
3. Read Commited 可讀已提交
4. Read Uncommited 可讀未提交
隔離級別與並發性能的關系:
四種隔離機制的個人理解:
1,Read Uncommited 可讀未提交:字面意思可以讀取未提交的事務。在並發操作時,一個事務可以讀取另一個事務對數據的改動。可能發生臟讀,第二類更新丟失,幻讀,不可重復讀,不會發生第一類更新丟失。
2 Read Commited 可讀已提交:兩個事務之間已經提交的可以互讀。可能發生第二類更新丟失,幻讀,不可重復讀,不會發生臟讀,第一類更新丟失(根據其發生的原因)。
3 Repeatable Read 可重復讀:在事務執行期間會鎖定該事務以任何方式引用的所有行。如果在同一個事務中發出同一個SELECT語句兩次或更多次,那么產生的結果數據集總是相同的。因此,使用可重復讀隔離級別的事務可以多次檢索同一行集,並對它們執行任意操作,直到提交或回滾操作終止該事務。臟讀、不可重復的讀、第二類更新丟失現象都不會發生,但是幻讀會發生。
1. Serializable 串行化:Serializable是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免臟讀、不可重復讀,還避免了幻像讀。
四 事務隔離機制使用:
MySQL的默認事務隔離級別是:Repeatable Read
SQL Server的默認事務隔離級別是:Read Commited
Oracle數據庫支持Read Commited 和 Serializable這兩種事務隔離級別。Oracle 默認使用的是Read Commited
應用時設置數據庫的隔離級別:
1.在Hibernate的配置文件中可以顯示的配置數據庫事務隔離級別。每一個隔離級別用一個整數表示:
8 - Serializable 串行化
4 - Repeatable Read 可重復讀
2 - Read Commited 可讀已提交
1 - Read Uncommited 可讀未提交
在hibernate.cfg.xml文件中加入<property name="hibernate.connection.isolation">2</property>
2.在spring與hibernate整合時,
1.在spring的配置文件的 SessionFactory bean中添加hibernate.connection.isolation屬性
2.使用注解@Transactional(isolation=Isolation.REPEATABLE_READ),
isolation:設隔離級別。默認為底層數據庫的隔離級別
noRollbackFor:指定遇到特定的異常不強制回滾.@Transactional(notRollbackFor=RunTimeException.class)運行異常不回滾(rollbackFor相反)
noRollbackForClassName:指定遇到多個特定的異常不強制回滾。RollbackForClassName相反
propagation:指定事務的傳播行為、修飾bean對象表示對該對象起作用,修飾bean方法只對該方法有效
1、PROPAGATION_REQUIRED:如果當前沒有事務,就創建一個新事務,如果當前存在事務,就加入該事務,該設置是最常用的設置。
2、PROPAGATION_SUPPORTS:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。‘
3、PROPAGATION_MANDATORY:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就拋出異常。
4、PROPAGATION_REQUIRES_NEW:創建新事務,無論當前存不存在事務,都創建新事務。
5、PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
6、PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
7、PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。
五 數據庫悲觀鎖和樂觀鎖
http://www.cnblogs.com/wang-meng/p/5506943.html
參考資料:http://blog.csdn.net/fg100emil/article/details/2927098
http://www.cnblogs.com/jerryxing/archive/2012/04/24/2468999.html
小白第一次寫博客,望各位大神指出錯誤。學習改進