【一】事務傳播的級別:按照對事務要求的程度,從低--->高可以分成下面7個級別
PROPAGATION_NEVER
總是非事務地執行,如果存在一個活動事務,則拋出異常
PROPAGATION_NOT_SUPPORTED
總是非事務地執行,并掛起任何存在的事務。
PROPAGATION_SUPPORTS
如果沒有事務,則非事務的執行。如果存在一個事務,則加入當前事務。
PROPAGATION_REQUIRED
如果沒有事務,則開啟一個新的事務。如果存在一個事務,則加入當前事務。
PROPAGATION_NESTED
如果沒有活動事務, 則按PROPAGATION_REQUIRED 屬性執行,如果一個活動的事務存在,則運行在一個嵌套的事務中.
PROPAGATION_REQUIRES_NEW
總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。
PROPAGATION_MANDATORY
如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。
【二】PROPAGATION_NESTED 與PROPAGATION_REQUIRES_NEW的區別:
PROPAGATION_REQUIRES_NEW每次開啟一個新的事務,同時掛起前一個正在運行的事務,開啟的新事務會獨立提交/回滾。之后被掛起的前一個事務繼續運行,在結束時提交或回滾。
由此看來,當使用PROPAGATION_REQUIRES_NEW時,服務層的內部其實是由多個獨立的小事務組成的一個大的事務。每個小事務彼此獨立,互不影響。一旦內層事務進行了提交,外層事務不能對其進行回滾。而且它需要JTA事務管理器的支持。
PROPAGATION_NESTED并不開啟新的事務,它使用save point來代替事務,它可以選擇在自己的邏輯內回滾,但它不能在自己的邏輯內提交,而必須等到外層的邏輯提交時一并提交。
由此看來,當使用PROPAGATION_NESTED時,服務層的內部只有一個事務存在,內嵌的事務回滾不會引起外層的事務回滾(如同上面說的,它可以在自己的邏輯內回滾),但外層的事務回滾會引起內嵌的事務回滾(因為內嵌的事務必須等到外層事務提交時才一并提交)。需要JDBC 3.0以上驅動及1.4以上的JDK版本支持。
【三】PROPAGATION_XXX的設置和性能優化
一般來說,PROPAGATION_REQUIRED的傳播級別就已經夠了。對于長時間、可分段的任務,如果也采用一個大的事務一次性提交,則一旦失敗代價太大了。最典型的例子就是:大批量的數據導入,你總不能因為一條數據錯了而將其它插入全部回滾吧!
這時可以考慮劃分為小段的PROPAGATION_REQUIRED事務進行,多次獨立提交事務。
也考慮考慮設置為PROPAGATION_NESTED,因為JDBC 3.0提供了save point機制,可以在事務未提交的情況下保存事務中間的狀態,一旦回滾不會回滾全部,而是只回滾到save point點(根據時間)。那么我們可以把大的事務劃分成多個小的內嵌事務,每個內嵌事務執行成功后刷新save point,如果全部成功則一次性提交,如果中間失敗了則回滾則上一個save point,同時繼續下一個內嵌事務,不怕將前面尚未提交的其它事務操作全部回滾。
和PROPAGATION_REQUIRED相比,好處就是事務提交的次數少了,可以一次性寫入
posted on 2010-03-15 11:09
Paul Lin 閱讀(2611)
評論(0) 編輯 收藏 所屬分類:
J2EE 框架