數據庫事務的概念:事務能夠看作是一系列操做組成的工做單元。這個工做單元是一個完整主體。工做單元中的一系列操做要麼都執行成功,要麼都執行失敗。web
事務的四個特性(ACID):數據庫
1.原子性(Atomicity):事務是不可分割的工做單元。要麼都執行成功,要麼都不成功編程
2.一致性(Consistency):事務的執行不會破壞數據庫的完整性。併發
3.隔離性(Isolation):併發的事務之間相互之間不影響,經過事務隔離級別來指定隔離性ui
4.持久性(Durability):事務一旦執行完成以後,對數據庫的修改是永久性的。不會被外界因素改變。spa
在實際的開發過程當中,常常會後併發訪問數據庫的狀況。即多個事務同時修改數據庫信息。常見的問題包括:.net
丟失更新:當某一個事務修改了數據庫的某條記錄,在該事務提交前,另外一個事務也對該條記錄作了修改。前一個事務的修改被後面的事務修改給覆蓋了。代理
致使第一個事務修改的數據丟失,這是因爲沒有對修改記錄加鎖形成的。接口
髒讀:一個事務讀到了另外一個事務還未提交的數據。事務
不可重複讀:同一個事務兩次查詢同一條記錄返回的結果不同,因爲兩次查詢中另外一個事務對該記錄修改形成的。
幻讀:同一事務兩次查詢結果不一樣,因爲兩次查詢中另以事務又插入了新的數據,兩次查詢出了兩批記錄,好像出現了幻覺同樣。
上述問題的發生都是因爲併發事務之間的隔離沒有作好而引發的。解決這些問題就是設置合理的事務隔離級別。
事務的隔離級別包括:未提交讀(read_uncommitted)、提交讀(read_commit)、可重複讀(repeatable_read)、序列化(serialable).
四個隔離級別的隔離性是遞增的。隔離級別越高,數據庫的併發能力就越差,因此在實際開發過程當中須要在數據庫併發能力和知足實際業務要求之間作權衡。
未提交讀:最低的隔離級別,可能致使丟失更新、髒讀、不可重複讀、幻讀。
提交讀:一個事務只能讀到其餘事務提交以後的數據,這個是大多數數據庫默認的隔離級別。能夠避免丟失更新和髒讀。仍有可能形成不可重複讀和幻讀。
可重複讀:能夠避免丟失更新、髒讀、不可重複讀。可能形成幻讀。
序列化:最高的隔離級別,事務之間沒有併發能力,全部事務都是串行化運行的。能夠避免丟失更新、髒讀、不可重複讀、幻讀。
Spring 提供了統一的事務管理。根據事務的配置方式不一樣能夠分爲:編程式事務和聲明式事務兩種。
建議使用聲明式事務,其中聲明式事務又分爲兩種:一種是使用註解@Transactional聲明;另外一種是使用切面的方式統一進行攔截。
註解方式相對靈活,切面方式比較依賴前期的約定和配置。因爲前期的項目約定並不完整,咱們項目中採用了註解的方式進行事務的控制。
Spring使用@Transaction來指定事務屬性,能夠在接口、類或方法上指定,若是類和方法上都指定了
@Transaction ,則方法上的事務屬性被優先使用,具體屬性以下:
• value:指定事務管理器名字,默認使用<tx:annotation-driven/>指定的事務管理器,用於支持多事務管理器環境;
• propagation:指定事務傳播行爲,默認爲Required,使用Propagation.REQUIRED指定;
• isolation:指定事務隔離級別,默認爲「DEFAULT」,使用Isolation.DEFAULT指定;
• readOnly:指定事務是否只讀,默認false表示事務非只讀;
• timeout:指定事務超時時間,以秒爲單位,默認-1表示事務超時將依賴於底層事務系統;
• rollbackFor:指定一組異常類,遇到該類異常將回滾事務;
• rollbackForClassname:指定一組異常類名字,其含義與<tx:method>中的rollback-for屬性語義徹底同樣;
• noRollbackFor:指定一組異常類,即便遇到該類異常也將提交事務,即不回滾事務;
• noRollbackForClassname:指定一組異常類名字,其含義與<tx:method>中的no-rollback-for屬性語義徹底同樣;
下面介紹一下propagation和isolation屬性對應的值的含義:
1.propagation對應的值是一個枚舉包含如下幾個值:
REQUIRED:這是propagation的默認值,若是當前存在事務則加入事務,若是不存在事務則建立一個事務。
SUPPORTS:若是當前存在事務則加入事務,若是不存在就已無事務的方式運行。
MANDATORY:強制必須當前有事務存在,若是不存在事務則拋出異常。
REQUIRES_NEW:無論當前有沒有事務,都建立一個新的事務。
NOT_SUPPORTED:若是當前存在事務,那麼中止使用事務。
NEVER:強制不使用事務,若是當前存在事務則拋出異常
NESTED:若是一個活動的事務存在,則運行在一個嵌套的事務中,若是沒有活動的事務,則按照REQUIRED屬性執行,它使用一個單獨的事務。
這個事務擁有多個回滾的保存點,內部事務的回滾不會對外部事務形成影響,它只對DataSource TransactionManager事務管理器起效。
2.isolation對應的值也是一個枚舉包含如下幾個值(對應前面講到的開發常見問題解決方案):
DEFAULT:默認的隔離級別
READ_UNCOMMITTED:未提交讀
READ_COMMITTED:提交讀
REPEATABLE_READ:可重複讀
SERIALIZABLE:序列化
Spring官方文檔上的描述是這樣的:
You can place the @Transactional annotation before an interface definition, a method on an Interface a class definition, or a public method on a class
可是建議只在實現類和實現類的方法上進行註解的使用。由於若是使用CGLIB的方式代理機制接口上的@Transactional是不會被實現類集成下來的,可能會形成配置事務沒法使用的問題。先寫到這若有疑問歡迎前來探討!