mysql數據庫,當且僅當引擎是InnoDB,才支持事務;
隔離級別(Isolation)
隔離級別是指若干個併發的事務之間的隔離程度,與我們開發時候主要相關的場景包括:髒讀取、重複讀、幻讀。我們可以看 org.springframework.transaction.annotation.Isolation 枚舉類中定義了五個表示隔離級別的值:
public enum Isolation { DEFAULT(-1), READ_UNCOMMITTED(1), READ_COMMITTED(2), REPEATABLE_READ(4), SERIALIZABLE(8); }
隔離級別
事務的隔離級別分爲:
未提交讀(read uncommitted)
已提交讀(read committed)
可重複讀(repeatable read)
串行化(serializable)
未提交讀:A事務已執行,但未提交;B事務查詢到A事務的更新後數據;A事務回滾;—出現髒數據
已提交讀:A事務執行更新;B事務查詢;A事務又執行更新;B事務再次查詢時,前後兩次數據不一致;—不可重複讀:A事務無論執行多少次,只要不提交,B事務查詢值都不變;B事務僅查詢B事務開始時那一瞬間的數據快照;
串行化: 不允許讀寫併發操作,寫執行時,讀必須等待;
Mysql 中的事務查詢
//查看當前事物級別:
SELECT @@tx_isolation;
//設置read uncommitted級別:
set session transaction isolation level read uncommitted;
//設置read committed級別:
set session transaction isolation level read committed;
//設置repeatable read級別:
set session transaction isolation level repeatable read;
//設置serializable級別:
set session transaction isolation level serializable;
Spring中如何設置事務隔離級別
@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)
public class DefaultFooService implements FooService {
public void getSomething(Foo foo) {
// do something
}
//方法上註解屬性會覆蓋類註解上的相同屬性
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void updateFoo(Foo foo) {
// do something
} }
Propagation:傳播行爲
所謂事務的傳播行爲是指,如果在開始當前事務之前,一個事務上下文已經存在,此時有若干選項可以指定一個事務性方法的執行行爲。
我們可以看 org.springframework.transaction.annotation.Propagation 枚舉類中定義了6個表示傳播行爲的枚舉值:
public enum Propagation { REQUIRED(0), SUPPORTS(1), MANDATORY(2), REQUIRES_NEW(3), NOT_SUPPORTED(4), NEVER(5), NESTED(6); }
REQUIRED :如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。
SUPPORTS :如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。
MANDATORY :如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。
REQUIRES_NEW :創建一個新的事務,如果當前存在事務,則把當前事務掛起。
NOT_SUPPORTED :以非事務方式運行,如果當前存在事務,則把當前事務掛起。
NEVER :以非事務方式運行,如果當前存在事務,則拋出異常。
NESTED :如果當前存在事務,則創建一個事務作爲當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價於 REQUIRED 。