Spring Transaction配置簡介
可以從以下多個維度配置Spring事務。
propagation
表示當前事務與父事務(同一個執行緒中之前申明事務)的關係。父子事務體現為,方法呼叫棧的呼叫先後順序。
說得更直白點,就是一個方法Method1呼叫另外一個申明Transaction的Method2,Method1可能申明Transaction,也可能沒有,Method2如何處理Transaction的問題。
PROPAGATION_REQUIRED
如果父事務存在,使用父事務,沒有則建立一個新的。Spring預設值。
例子:@Transactional(propagation=Propagation.REQUIRED)
PROPAGATION_SUPPORTS
如果父事務存在,使用父事務,沒有則就不使用事務。
例子:@Transactional(propagation=Propagation.PROPAGATION_SUPPORTS)
PROPAGATION_MANDATORY
如果父事務存在,使用父事務,沒有則丟擲異常。
例子:@Transactional(propagation=Propagation.PROPAGATION_MANDATORY)
PROPAGATION_REQUIRES_NEW
總是建立一個新的事務。如果父事務存在,父事務暫時掛起,沒有則無需額外處理。
例子:@Transactional(propagation=Propagation.PROPAGATION_REQUIRES_NEW)
PROPAGATION_NOT_SUPPORTED
無論父事務存在還是不存在,總是非事務處理,不用事務,父事務有的話暫時掛起。
例子:@Transactional(propagation=Propagation.PROPAGATION_NOT_SUPPORTED)
PROPAGATION_NEVER
如果父事務存在,丟擲異常,不存在則非事務處理。
例子:@Transactional(propagation=Propagation.PROPAGATION_NEVER)
PROPAGATION_NESTED
與PROPAGATION_REQUIRED效果相同,使用範圍暫時只支援JDBC3.0。
例子:@Transactional(propagation=Propagation.PROPAGATION_NESTED)
isolation
刻畫不同事務之間資料的可見性,資料的隔離級別。ISOLATION_READ_UNCOMMITTED,ISOLATION_READ_COMMITTED,ISOLATION_REPEATABLE_READ,ISOLATION_SERIALIZABLE隔離級別逐漸增強。基本與關係型
資料庫的隔離級別一致。
ISOLATION_DEFAULT
具體的值依賴與底層資料來源的隔離級別。Spring預設值。
例子:@Transactional(isolation=Isolation.ISOLATION_DEFAULT)
ISOLATION_READ_UNCOMMITTED
可以看到別的事務未提交的資料。隔離級別很差。
例子:@Transactional(isolation=Isolation.ISOLATION_READ_UNCOMMITTED)
ISOLATION_READ_COMMITTED
可以看到別的事務提交了的資料。避免髒讀。
例子:@Transactional(isolation=Isolation.ISOLATION_READ_COMMITTED)
ISOLATION_REPEATABLE_READ
避免髒讀,也避免了non-repeatable read。
例子:@Transactional(isolation=Isolation.ISOLATION_REPEATABLE_READ)
ISOLATION_SERIALIZABLE
避免髒讀,也避免了non-repeatable read和phantom read。最強隔離級別。
例子:@Transactional(isolation=Isolation.ISOLATION_SERIALIZABLE)
timeout
以秒為單位的事務超時時間。預設值-1,表示沒有超時時間。
例子:@Transactional(timeout=30)
readOnly
提示事務管理器,方法內部只涉及到讀操作,Spring預設為false。依賴於底層事務管理器的解釋,並不一定有效果。
例子:@Transactional(readOnly=true)
rollbackFor
遇到什麼樣的異常事務會回滾。Spring預設值是RuntimeException,Checked Exception不會回滾。
例子:@Transactional(rollbackFor=Exception.class)
結論
Spring的預設值基本能夠滿足一般事務需求。事務最佳實踐是找到業務單元,在最頂層標註Transactional。
需要注意的有以下幾點:
rollbackFor引數,Spring預設為RuntimeException,一定要保證服務丟擲的是執行時異常或者其子類。另外一個辦法是標註為@Transactional(rollbackFor=Exception.class)。
readOnly不一定有優化效果,不要過分依賴。
isolation基本不會特別的去配置。除非真的完全理解其意義,否則不要亂改。
propagation看起來有很多選項,過於複雜,但是真正常用的就只有PROPAGATION_REQUIRED和PROPAGATION_REQUIRES_NEW