spring 基於AOP事務控制實現的基礎
阿新 • • 發佈:2019-02-17
事務控制比較重要的應該是事務的傳播--propagation,實現的基礎:ThreadLocal。
...
...
TransactionAspectSupport 內部transactionInfoHolder 線上程的範圍內持有當前的TransactionInfo。
建立事務的過程中,會構造TransactionInfo,並且儲存上一級TransactionInfo,繫結至當前執行緒,也就是說事務呼叫鏈的資訊以thread為載體,以TransactionInfo 為node,形成事務資訊的連結串列。
事務巢狀的node - TransactionInfo:
/** * Opaque object used to hold Transaction information. Subclasses * must pass it back to methods on this class, but not see its internals. */ protected final class TransactionInfo { // 儲存當前事務manager private final PlatformTransactionManager transactionManager; // @Transactional 屬性 private final TransactionAttribute transactionAttribute; private final String joinpointIdentification; // 事務控制關鍵 private TransactionStatus transactionStatus; // 儲存上一級的TransactionInfo,是的,一定是上一級的 private TransactionInfo oldTransactionInfo; }
自定義ThreadLocal:
/** * ThreadLocal subclass that exposes a specified name * as toString() result (allowing for introspection). * * @author Juergen Hoeller * @since 2.5.2 * @see NamedInheritableThreadLocal */ public class NamedThreadLocal extends ThreadLocal { private final String name; /** * Create a new NamedThreadLocal with the given name. * @param name a descriptive name for this ThreadLocal */ public NamedThreadLocal(String name) { Assert.hasText(name, "Name must not be empty"); this.name = name; } @Override public String toString() { return this.name; } }
...
實踐,我們的巢狀事務應該怎麼寫:
1.service 分層呼叫,整體事務service,子業務service;
2.所有涉及的service 都需要@Transactional。
...
總結,事務commit 發生的情況:
未設定commit時,原生的jdbc操作,直接commit;
無事務控制的mybaitis 操作,SqlSessionTemplate 檢測到沒有事務,執行commit;
有事務控制的jdbc、mybaitis 操作,判斷TransactionStatus確定執行commit;
...
多事務管理的控制需要注意的:
明確指定value = "資料來源對應的txManager", 否則會導致的第二種
巢狀事務統一commit 的判斷時機:
commitTransaction 判斷status.isNewTransaction() 決定是否doCommit();