A.createA()是一個事務,createA()方法本身會createAentity(),生成A對象。里面包含調用了 B.createB(), C.createC()方法。
B.createB()也是一個事務,包含調用了 B1.createB1(),C1.createC1()方法。B1.createB1會重新從數據庫查找A對象,並據此做一些判斷來執行后續邏輯。
所以A的createA()事務方法嵌套調用了 B.createB()事務方法,並且B方法內使用了A創建的對象。
問:A,B如何設置事務的傳播屬性?
事務的傳播屬性:
PROPAGATION_REQUIRED: 支持當前事務,沒有則新建
PROPAGATION_REQUIRESNEW: 新建事務,如果當前存在事務,把當前事務掛起
PROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行
PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常
PROPAGATION_NOT_SUPPORTED:以非事務方式執行,如果當前存在事務,就把當前事務掛起。也就是說業務方法不需要事務
PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。也就是說業務方法絕對不能在事務范圍內執行
PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中。 如果沒有活動事務, 則按REQUIRED屬性執行
實際上,使用的是前兩種:required, requiresNew. 兩者區別在於:
PROPAGATION_REQUIRES_NEW 啟動一個新的, 不依賴於環境的 "內部" 事務. 這個事務將被完全 commited 或 rolled back 而不依賴於外部事務, 它擁有自己的隔離范圍, 自己的鎖, 等等. 當內部事務開始執行時, 外部事務將被掛起, 內務事務結束時, 外部事務將繼續執行。他是其一個單獨的事務,自我完全隔離。
PROPAGATION_REQUIRED 如果當前存在一個事務,則加入當前事務。如果不存在任何事務,則創建一個新的事務。他可能會兩個事務合並成一個,或外部沒有事務時自己創建一個事務。一般作為事務默認的傳播行為。
所以A.createA() 方法使用 REQUIRES_NEW隔離級別;B.createB()方法使用 REQUIRED 隔離級別。因為B需要讀取到A先前創建的 AEntity。如果B使用的是REQUIRES_NEW隔離級別,那么將讀取不到A創建但尚未commit的AEntity,導致程序錯誤。