补充spring事务传播性没有考虑的几种情况
spring傳播機制的講解參考:
https://segmentfault.com/a/1190000013341344#articleHeader3
http://blog.51cto.com/jaeger/1761660
以下15種情況,大多都是網上講解spring傳播性不會講的,以下都是新自測試過的結果,并寫了幾條總結。
spring事務的幾種情況
需要注意的是,如果拋出的異常不是RuntimeException而是Exception,則需要通過rollbakfor指定,不然事務當中拋出的Exception異常是不回滾的。
1.同類中,事務方法a調用非事務方法b。在b的最后拋異常,a捕獲b的異常。結果是:都不回滾。
2.同類中,事務方法a調用非事務方法b。在b的最后拋異常,a不捕獲b的異常。結果是:都回滾。
3.同類中,事務方法a調用非事務方法b。在a的最后拋出異常。結果是:都回滾。
4.同類中,事務方法a調用配置過事務的方法b。在b的最后拋出異常,a捕獲b的異常。結果是:都不回滾。
5.同類中,事務方法a調用配置過事務的方法b。在b的最后拋出異常,a不捕獲b的異常。結果是:都回滾。
6.同類中,事務方法a調用配置過事務的方法b。在a的最后拋出異常,結果是:都回滾。
7.同類中,非事務方法a調用配置過事務的方法b,在b最后拋出異常,a捕獲b的異常。結果是:都不回滾。
8.同類中,非事務方法a調用配置過事務的方法b,在b最后拋出異常,a不捕獲b的異常。結果是:都不回滾。
9.同類中,非事務方法a調用配置過事務的方法b,在a最后拋出異常。結果是:都不回滾。
10.非同類中,事務方法a調用非事務方法b,在b的最后拋出異常,a捕獲導常。結果是:都不回滾。
11.非同類中,事務方法a調用非事務方法b,在b的最后拋出異常,a不捕獲異常。結果是:都回滾。
12.非同類中,事務方法a調用非事務方法b,在a的最后拋出異常。結果是:都回滾。
13.非同類中,事務方法a調用嵌套事務方法b,在b的最后拋出異常,a捕獲b的異常。結果是:只有b回滾。
14.非同類中,事務方法a調用嵌套事務方法b,在b的最后拋出異常,a不捕獲b的異常。結果是:都回滾。
15.非同類中,事務方法a調用嵌套事務方法b,在a的最后拋出異常。結果是:都回滾。
16.非同類中,非事務方法a調用事務方法b,在b的最后拋出異常,a捕獲b的異常。結果是:只有b回滾。
17.非同類中,非事務方法a調用事務方法b,在b的最后拋出異常,a不捕獲b的異常。結果是:只有b回滾。
18.非同類中,非事務方法a調用事務方法b,在a的最后拋出異常。結果是:都不回滾。
19.非同類中,非事務方法a調用嵌套事務方法b,在b的最后拋出異常,a捕獲b的異常。結果是:只有b回滾。
20.非同類中,非事務方法a調用嵌套事務方法b,在b的最后拋出異常,a不捕獲b的異常。結果是:只有b回滾。
21.非同類中,非事務方法a調用嵌套事務方法b,在a的最后拋出異常。結果是:都不回滾。
22.非同類中,事務方法a多級嵌套調用非事務方法,在任一級非事務方法中拋出異常,a捕獲異常,結果是都不回滾。
23.非同類中,事務方法a多級嵌套調用非事務方法,在任一級非事務方法中拋出異常,a不捕獲異常。結果是都回滾。
24.非同類中,事務方法a多級嵌套調用非事務方法,在a的最后拋出異常。結果是都回滾。
以下是對第18條的一個舉例:
A類中,a為非事務方法
public void a() throws Exception {Task t = new Task();t.setOrderContent("非事務方法測試A");dao.insert(t);new B().b();throw new Exception();}B類中,b為事務方法
public void b() {Task t = new Task();t.setOrderContent("事務方法測試B");dao.insert(t);}以下是對第13條的一個舉例:非同類中,事務方法a調用嵌套事務方法b,在b的最后拋出異常,a捕獲b的異常。結果是:只有b回滾。
A類中,a為事務方法
public void a() {try{Task t = new Task();t.setOrderContent("非事務方法測試A");// 由于異常被捕獲了,所以下面的插入不會回滾,因為異常被捕獲后,方法a感知不到了dao.insert(t);new B().b();}catch(Exception e){e.printStack();}}B類中,b為嵌套事務方法
public void b() throws Exception {Task t = new Task();t.setOrderContent("事務方法測試B");dao.insert(t);throw new Exception();}總結:
spring的事務傳播屬性不適用于同類中的方法調用,即事務方法在被同類中的方法調用時會被當作非事務方法。
事務方法調用非事務方法(包括本類中事務不生效的方法)時,事務方法捕獲了被調用方法里的異常時就都不會回滾,不捕獲就都回滾。
非事務方法調用非事務方法(包括本類中事務不生效的方法)和調用嵌套事務時一樣都不會互不影響,即都會自動提交。
事務方法多級嵌套調用非事務方法,和調用一級非事務方法結果是一致的,即只要事務方法捕獲了異常就都不回滾,不捕獲就都回滾。
一個方法b加入到事務方法a中時,不論b拋出的異常是否被a捕獲,結果是整個事務都會回滾。因為始終是一個事務。
事務方法a調用一個新開的事務方法b,在b的最后拋出異常,a捕獲異常。結果是只有b回滾。因為都不在同一個事務當中了。
事務在spring中的幾個重點:
事務的隔離級別是數據庫本身的事務功能,然而事務的傳播屬性則是Spring自己為我們提供的功能,數據庫事務沒有事務的傳播屬性這一說法。
事務的前提是要數據庫支持事務
事務傳播機制只適用于不同bean之間的方法調用
只要一個方法開啟了事務,那么就從此時設置了一個事務點。
一個線程的事務不會影響到另外一個線程的事務。例如,插入日志的方法是需要始終保持成功的,而不希望因為事務內的某些方法導致的回滾而回滾,所以一般的都會新開線程來執行插入日志的方法。
一個線程在沒有結束當前事務的時候,是無法釋放資源來執行其它事務的。
事務在數據庫中的幾個重點:
數據庫執行事務的時候,是先將數據插入到日志中,如果沒有遇到回滾,則在提交事務的時候將日志操作同步到數據庫。如果回滾的話,則日志的操作不再插入數據庫中。
如果發生回滾,則主鍵還是會增大的即主鍵會變得不連續。例如,本應該插入的數據id為100,但是發生了回滾,則后面再正確插入的數據的主鍵會是101。
JDBC對事務的支持是放在Connection連接中的。
補充
如果使用的@Transactionl注解,最好不要加在接口上。
在接口上使用 @Transactional 注解,只能當你設置了基于接口的代理時它才生效。因為注解是 不能繼承 的,這就意味著如果正在使用基于類的代理時,那么事務的設置將不能被基于類的代理所識別,而且對象也將不會被事務代理所包裝。
總結
以上是生活随笔為你收集整理的补充spring事务传播性没有考虑的几种情况的全部內容,希望文章能夠幫你解決所遇到的問題。