SSM框架的整合學到尾聲了,最后的時候接觸到了事務傳播機制,有點多,就記下來吧
0.值得注意的坑(SSM事務回滾失效)
在spring-mvc.xml文件中,如果你配置包掃描的時候,是掃描項目下所有的包,比如這樣(我的整個項目都在top文件夾下)
那么你的事務機制會出問題,因為spring-mvc是一個子容器,不具有事務功能,而spring-config是頂級父容器,有事務功能,如果你在spring-mvc.xml內掃描了處理事務的service類,會導致事務功能失效
所以,記得要排除掉處理事務的類,只需要把上面的代碼改成
1 <context:component-scan base-package="top.**"> 2 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> 3 <!--這樣設置之后就可以讓這個子容器不加載servicer--> 4 </context:component-scan>
然后事務功能就正常了
1.事務的使用(只介紹注釋方式)
在負責與數據庫交互的方法前加上注釋 @Transactional 這樣這個方法調用時就會開啟一個事務,方法結束時該事務結束
例子:
1 @Transactional //事務注釋,涉及到改變數據庫的最好都加上 2 public int createStudent(Student student) { 3 studentMapper.insertSelective(student); //接收student並調用studentMapper的insertSelective()方法來寫入數據庫 4 return 0; 5 }
2.事務注釋的屬性
在事務注釋@Transactional后可以添加括號,里面寫上一些屬性來改變運行機制,如果不加屬性的話,遇到檢查錯誤就會事務回滾
①忽略錯誤,事務不回滾(有風險,用不用看具體情況)
1 @Transactional(noRollbackFor = RuntimeException.class) //這里的意思是當該事務運行過程中發生RuntimeException錯誤的時候,事務繼續,不回滾
②碰到指定錯誤也回滾
1 @Transactional(RollbackFor = RuntimeException.class) //遇到指定錯誤也要回滾,比如你可以自定義一個錯誤類,設置出現該錯誤是要回滾
3.事務傳播機制
什么是事務傳播?我對他的理解就是:在事務與事務之間發生嵌套或者交叉等等情況的時候,來處理他們之間運行的邏輯關系的機制
簡單言之,就是負責處理事務之間的關系
用法:和上面一樣,在注釋后面加個(),再寫上對應字段
①默認機制(REQUIRED)
1 @Transactional(propagation = Propagation.REQUIRED)
這是系統默認的機制,特點是:在執行這個事務前,系統會檢測在他之前是否已經存在事務,即他是否已經被包含在一個事務里,如果有,則加入該事務來運行,如果沒有,則新建一個事務運行.
這種運行邏輯符合95%的情況,平時用的最多的也是這種,反正是默認的,肯定泛用性高啦
②SUPPORTS
1 @Transactional(propagation = Propagation.SUPPORTS)
特點:如果檢測到前面有開啟中的事務,則加入該事務中,如果前面沒有事務,則按照非事務的方式運行下去
③MANDATORY
1 @Transactional(propagation = Propagation.MANDATORY)
特點:該事務前面必須要要有一個開啟着的事務;即如果系統在這個事務之前沒有檢測到開啟的事務,會報錯. 一般用於不能獨立執行,必須要在其他事務中運行的代碼,同時也是檢查是否有事務包圍的好手段
④REQUIRES_NEW
1 @Transactional(propagation = Propagation.REQUIRES_NEW)
特點:運行到這里時,都會新建立一個事務,如果在它之前有開啟的事務,則會把它之前的事務暫時掛起暫停,等待它運行完成后,才會繼續運行之前的事務
⑤NOT_SUPPORTED
1 @Transactional(propagation = Propagation.NOT_SUPPORTED)
特點:運行到這里時,檢查之前有沒有開啟的事務,有的話就把它掛起暫停,等自己按照非事務的方式運行完成后,再運行前面的事務(與④的區別是它本身不會新建一個事務)
⑥NEVER
1 @Transactional(propagation = Propagation.NEVER)
特點:運行到這里時,系統會檢查前面是否有開啟着的事務,如果有,會報錯,沒有則按照非事務的方式執行
⑦NESTED
1 @Transactional(propagation = Propagation.NESTED)
特點:如果前面有開啟的事務,則還是會新建一個事務嵌套在其中執行,如果前面沒有開啟着的事務,則也新建一個事務執行