事務屬性的種類
事務屬性的種類: 傳播行為、隔離級別、只讀和事務超時
a) 傳播行為定義了被調用方法的事務邊界。
傳播行為 |
意義 |
PROPERGATION_MANDATORY |
表示方法必須運行在一個事務中,如果當前事務不存在,就拋出異常 |
PROPAGATION_NESTED |
表示如果當前事務存在,則方法應該運行在一個嵌套事務中。否則,它看起來和 PROPAGATION_REQUIRED 看起來沒什麽倆樣 |
PROPAGATION_NEVER |
表示方法不能運行在一個事務中,否則拋出異常 |
PROPAGATION_NOT_SUPPORTED |
表示方法不能運行在一個事務中,如果當前存在一個事務,則該方法將被掛起 |
PROPAGATION_REQUIRED |
表示當前方法必須運行在一個事務中,如果當前存在一個事務,那麽該方法運行在這個事務中,否則,將創建一個新的事務 |
PROPAGATION_REQUIRES_NEW |
表示當前方法必須運行在自己的事務中,如果當前存在一個事務,那麽這個事務將在該方法運行期間被掛起 |
PROPAGATION_SUPPORTS |
表示當前方法不需要運行在一個是事務中,但如果有一個事務已經存在,該方法也可以運行在這個事務中 |
b) 隔離級別
在操作數據時可能帶來 3 個副作用,分別是臟讀、不可重復讀、幻讀。為了避免這 3 中副作用的發生,在標準的 SQL語句中定義了 4 種隔離級別,分別是未提交讀、已提交讀、可重復讀、可序列化。而在 spring 事務中提供了 5 種隔離級別來對應在 SQL 中定義的 4 種隔離級別,如下:
隔離級別 |
意義 |
ISOLATION_DEFAULT |
使用後端數據庫默認的隔離級別 |
ISOLATION_READ_UNCOMMITTED |
允許讀取未提交的數據(對應未提交讀),可能導致臟讀、不可重復讀、幻讀 |
ISOLATION_READ_COMMITTED |
允許在一個事務中讀取另一個已經提交的事務中的數據(對應已提交讀)。可以避免臟讀,但是無法避免不可重復讀和幻讀 |
ISOLATION_REPEATABLE_READ |
一個事務不可能更新由另一個事務修改但尚未提交(回滾)的數據(對應可重復讀)。可以避免臟讀和不可重復讀,但無法避免幻讀 |
ISOLATION_SERIALIZABLE |
這種隔離級別是所有的事務都在一個執行隊列中,依次順序執行,而不是並行(對應可序列化)。可以避免臟讀、不可重復讀、幻讀。但是這種隔離級別效率很低,因此,除非必須,否則不建議使用。 |
c) 只讀
如果在一個事務中所有關於數據庫的操作都是只讀的,也就是說,這些操作只讀取數據庫中的數據,而並不更新數據,那麽應將事務設為只讀模式( READ_ONLY_MARKER ) , 這樣更有利於數據庫進行優化 。
因為只讀的優化措施是事務啟動後由數據庫實施的,因此,只有將那些具有可能啟動新事務的傳播行為(PROPAGATION_NESTED 、 PROPAGATION_REQUIRED 、 PROPAGATION_REQUIRED_NEW) 的方法的事務標記成只讀才有意義。
如果使用 Hibernate 作為持久化機制,那麽將事務標記為只讀後,會將 Hibernate 的 flush 模式設置為FULSH_NEVER, 以告訴 Hibernate 避免和數據庫之間進行不必要的同步,並將所有更新延遲到事務結束。
d) 事務超時
如果一個事務長時間運行,這時為了盡量避免浪費系統資源,應為這個事務設置一個有效時間,使其等待數秒後自動回滾。與設
置“只讀”屬性一樣,事務有效屬性也需要給那些具有可能啟動新事物的傳播行為的方法的事務標記成只讀才有意義。
摘抄自牛客網“請叫我猿叔叔”的習題解答
事務屬性的種類