Spring 事務屬性的種類
阿新 • • 發佈:2018-12-29
一、傳播行為
Spring 的傳播行為定義了被呼叫方法的事務邊界。
傳播行為 | 含義 |
---|---|
PROPAGATION_MANDATORY | 表示方法必須在事務中執行,如果當事務不存在,則會丟擲一個異常 |
PROPAGATION_NEVER | 表示當前方法不應該執行在事務上下文中,如果當前正有一個事務在執行,則會丟擲異常 |
PROPAGATION_REQUIRED | 表示當前方法必須執行在事務中。如果當前事務存在,方法將會在該事物中執行,否則,會啟動一個新的事務 |
PROPAGATION_REQUIRES_NEW | 表示當前方法必須執行在他自己的事務中,一個新的事務將被啟動。如果存在當前事務,在該方法執行期間,當前事務會被掛起。如果使用 JTATransactionManager,則需要訪問 TransactionManager |
PROPAGATION_NESTED | 表示如果當前以及存在一個事務,那麼該方法將會在巢狀事務中執行。巢狀的事務可以獨立於當前事務進行單獨地提交或回滾。如果當前事務不存在,那麼其行為與 PROPAGATION_REQUIRED 一樣。 |
PROPAGATION_SUPPORTS | 表示當前方法不需要事務上下文,但是如果存在當前事務的話,那麼該方法會在這個事務中執行 |
PROPAGATION_NOT_SUPPORTED | 表示該方法不應該執行在事務上下文中,如果當前正有一個事物在執行,則會丟擲一個異常 |
二、隔離級別
在操作資料時可能帶來 3 個副作用,分別是髒讀、不可重複讀、幻讀。為了避免這 3 中副作用的發生,在標準的 SQL 語句中定義了 4 種隔離級別,分別是未提交讀、已提交讀、可重複讀、可序列化。而在 spring 事務中提供了 5 種隔離級別來對應在 SQL 中定義的 4 種隔離級別,如下:
隔離級別 | 意義 |
---|---|
ISOLATION_DEFAULT | 使用後端資料庫預設的隔離級別 |
ISOLATION_READ_UNCOMMITTED | 允許讀取未提交的資料(對應未提交讀),可能導致髒讀、不可重複讀、幻讀 |
ISOLATION_READ_COMMITTED | 允許在一個事務中讀取另一個已經提交的事務中的資料(對應已提交讀)。可以避免髒讀,但是無法避免不可重複讀和幻讀 |
ISOLATION_REPEATABLE_READ | 一個事務不可能更新由另一個事務修改但尚未提交(回滾)的資料(對應可重複讀)。可以避免髒讀和不可重複讀,但無法避免幻讀 |
ISOLATION_SERIALIZABLE | 這種隔離級別是所有的事務都在一個執行佇列中,依次順序執行,而不是並行(對應可序列化)。可以避免髒讀、不可重複讀、幻讀。但是這種隔離級別效率很低,因此,除非必須,否則不建議使用。 |
三、只讀
如果在一個事務中所有關於資料庫的操作都是隻讀的,也就是說,這些操作只讀取資料庫中的資料,而並不更新資料,那麼應將事務設為只讀模式(READ_ONLY_MARKER ) , 這樣更有利於資料庫進行優化 。因為只讀的優化措施是事務啟動後由資料庫實施的,因此,只有將那些具有可能啟動新事務的傳播行為 (PROPAGATION_NESTED 、 PROPAGATION_REQUIRED 、 PROPAGATION_REQUIRED_NEW) 的方法的事務標記成只讀才有意義。
如果使用 Hibernate 作為持久化機制,那麼將事務標記為只讀後,會將 Hibernate 的 flush 模式設定為 FULSH_NEVER, 以告訴 Hibernate 避免和資料庫之間進行不必要的同步,並將所有更新延遲到事務結束。
四、事務超時
如果一個事務長時間執行,這時為了儘量避免浪費系統資源,應為這個事務設定一個有效時間,使其等待數秒後自動回滾。與設定“只讀”屬性一樣,事務有效屬性也需要給那些具有可能啟動新事物的傳播行為的方法的事務標記成只讀才有意義。