SpringBoot-事務管理

在Spring Boot中,當我們使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依賴的時候碟贾,框 架會自動默認分別注入DataSourceTransactionManager或JpaTransactionManager。所以我們不需要任何額外 配置就可以用@Transactional注解進行事務的使用缕陕。

spring Boot 使用事務非常簡單,首先使用注解 @EnableTransactionManagement 開啟事務支持后扛邑,然后在訪問數據庫的Service方法上添加注解 @Transactional 便可怜浅。

開啟事務

  • @EnableTransactionManagement 開啟事務支持
  • 在Service方法上添加注解 @Transactional
@EnableTransactionManagement
@SpringBootApplication(scanBasePackages = "zmx.springboot")
public class Application {
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean save(StUser entity) {
    // 其它邏輯
    boolean result = super.save(entity);
    // 其它邏輯
    throw new RuntimeException("測試的異常");
}

多個事務管理器

SpringBoot為我們自動做了蔬崩,對我們并不透明,如果有多個事務管理器沥阳,需要手動指定怎么處理@Transactional的value具體指定使用哪個事務管理器

/**
 * 多個事務管理
 */
@Configuration
public class MyTransactionManagementConfigurer implements TransactionManagementConfigurer {

    @Autowired
    @Qualifier("txManager1")
    private PlatformTransactionManager txManager1;

    /**
     * 創(chuàng)建一個自己的事務管理器
     *
     * @param dataSource
     * @return
     */
    @Bean(name = "txManager1")
    public PlatformTransactionManager txManager1(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "txManager2")
    public PlatformTransactionManager txManager2(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 其返回值代表在擁有多個事務管理器的情況下默認使用的事務管理器
     *
     * @return
     */
    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return txManager1;
    }
}
@Transactional(rollbackFor = Exception.class, value = "txManager2")
@Override
public boolean save(StUser entity) {
    boolean result = super.save(entity);
    throw new RuntimeException("測試的異常");
}

指定隔離級別

隔離級別是指若干個并發(fā)的事務之間的隔離程度,與我們開發(fā)時候主要相關的場景包括:臟讀取桐罕、重復讀桂敛、幻讀。org.springframework.transaction.annotation.Isolation枚舉類中定義了五個表示隔離級別的值:

public enum Isolation {

   /**
    * 這是默認值术唬,表示使用底層數據庫的默認隔離級別。對大部分數據庫而言滚澜,通常這值就是: READ_COMMITTED 
    */
   DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),

   /**
    * 該隔離級別表示一個事務可以讀取另一個事務修改但還沒有提交的數據。該級別不能防止臟讀和不可重復讀设捐。
    */
   READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),

   /**
    * 該隔離級別表示一個事務只能讀取另一個事務已經提交的數據。該級別可以防止臟讀萝招,這也是大多數情況下的推薦值。
    */
   READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),

   /**
    * 該隔離級別表示一個事務在整個過程中可以多次重復執(zhí)行某個查詢槐沼,并且每次返回的記錄都相同橡淆。即使在多次查詢之間有新增的數據滿足該查詢母赵,這些新增的記錄也會被忽略逸爵。該級別可以防止臟讀和不可重復讀凹嘲。
    */
   REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),

   /**
    * 所有的事務依次逐個執(zhí)行,這樣事務之間就完全不可能產生干擾周蹭,也就是說趋艘,該級別可以防止臟讀凶朗、不可重復讀以及幻讀瓷胧。但是這將嚴重影響程序的性能棚愤。通常情況下也不會用到該級別搓萧。
    */
   SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
}

指定方法:通過使用 isolation 屬性設置宛畦,例如:

@Transactional(isolation = Isolation.DEFAULT)

事務的傳播行為

傳播行為是指,如果在開始當前事務之前次和,一個事務上下文已經存在反肋,此時有若干選項可以指定一個事務性方法的執(zhí)行行為踏施。

public enum Propagation {

   /**
    * 如果當前存在事務石蔗,則加入該事務;如果當前沒有事務养距,則創(chuàng)建一個新的事務
    */
   REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

   /**
    * 如果當前存在事務,則加入該事務铃在;如果當前沒有事務碍遍,則以非事務的方式繼續(xù)運行定铜。
    */
   SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

   /**
    * 如果當前存在事務怕敬,則加入該事務揣炕;如果當前沒有事務东跪,則拋出異常畸陡。
    */
   MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

   /**
    * 創(chuàng)建一個新的事務虽填,如果當前存在事務丁恭,則把當前事務掛起斋日。
    */
   REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),

   /**
    * 以非事務方式運行牲览,如果當前存在事務恶守,則把當前事務掛起第献。
    */
   NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

   /**
    * 以非事務方式運行兔港,如果當前存在事務庸毫,則拋出異常衫樊。
    */
   NEVER(TransactionDefinition.PROPAGATION_NEVER),

   /**
    * 如果當前存在事務飒赃,則創(chuàng)建一個事務作為當前事務的嵌套事務來運行科侈;如果當前沒有事務盒揉,則該取值等價于 REQUIRED 
    */
   NESTED(TransactionDefinition.PROPAGATION_NESTED);

}

指定方法:通過使用 propagation 屬性設置兑徘,例如:

@Transactional(propagation = Propagation.REQUIRED)

事務實現機制

在應用系統調用聲明了 @Transactional 的目標方法時,Spring Framework 默認使用 AOP 代理挂脑,在代碼運行時生成一個代理對象藕漱,根據 @Transactional 的屬性配置信息,這個代理對象決定該聲明 @Transactional 的目標方法是否由攔截器 TransactionInterceptor 來使用攔截肋联,在 TransactionInterceptor 攔截時,會在目標方法開始執(zhí)行之前創(chuàng)建并加入事務橄仍,并執(zhí)行目標方法的邏輯, 最后根據執(zhí)行情況是否出現異常,利用抽象事務管理器 AbstractPlatformTransactionManager 操作數據源 DataSource 提交或回滾事務侮繁。


事務實現機制

TransactionTemplate

在spring-boot-autoconfigure.jar自動裝配了TransactionTemplate

@Configuration
@ConditionalOnClass({PlatformTransactionManager.class})
@AutoConfigureAfter({JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class})
@EnableConfigurationProperties({TransactionProperties.class})
public class TransactionAutoConfiguration {
        // ...
        @Bean
        @ConditionalOnMissingBean
        public TransactionTemplate transactionTemplate() {
            return new TransactionTemplate(this.transactionManager);
        }
}
try {
    transactionTemplate.execute(transactionStatus -> {
        //...
        // 通過拋出異常來回滾事務
        throw new RuntimeException("模擬插入記錄后失敗, 檢查是否回滾");
    });
} catch (Exception e) {
     System.out.println("Transaction rolled back");
}

參考于:Spring Boot事務管理詳解

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市娩贷,隨后出現的幾起案子,更是在濱河造成了極大的恐慌锁孟,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件品抽,死亡現場離奇詭異,居然都是意外死亡圆恤,警方通過查閱死者的電腦和手機南蓬,發(fā)現死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門哑了,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弱左,你說我怎么就攤上這事窄陡〔鸹穑” “怎么了跳夭?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵们镜,是天一觀的道長。 經常有香客問我模狭,道長颈抚,這世上最難降的妖魔是什么嚼鹉? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任驱富,我火速辦了婚禮,結果婚禮上匹舞,老公的妹妹穿的比我還像新娘。我一直安慰自己赐稽,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布姊舵。 她就那樣靜靜地躺著晰绎,像睡著了一般蠢莺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上躏将,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音祸憋,去河邊找鬼。 笑死肖卧,一個胖子當著我的面吹牛,可吹牛的內容都是我干的塞帐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼葵姥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了榔幸?” 一聲冷哼從身側響起允乐,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤削咆,失蹤者是張志新(化名)和其女友劉穎牍疏,沒想到半個月后拨齐,有當地人在樹林里發(fā)現了一具尸體鳞陨,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡瞻惋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年编矾,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馁害。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖碘菜,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情忍啸,我是刑警寧澤仰坦,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布计雌,位于F島的核電站,受9級特大地震影響凿滤,放射性物質發(fā)生泄漏妈橄。R本人自食惡果不足惜翁脆,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一眷蚓、第九天 我趴在偏房一處隱蔽的房頂上張望反番。 院中可真熱鬧沙热,春花似錦罢缸、人聲如沸篙贸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽养铸。三九已至雁芙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兔甘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工洞焙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓熔任,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唁情。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354