日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

SpringBoot整合分布式事務(wù),JTA+Atomikos實現(xiàn)多數(shù)據(jù)源

 碼農(nóng)9527 2021-07-21

在整合MySQL,JDBCTemplate這篇中的結(jié)尾,我們成功的向兩個數(shù)據(jù)庫中分別添加了一條數(shù)據(jù)。但是我們思考一下,如果PetsServiceImpl.java中的savePets()中如果發(fā)生異常了會怎么樣呢?  

@Override@Transactionalpublic void savePets(Pets pets) {
 petsDAO.save(pets, familyJdbcTemplate);
 petsDAO.save(pets, family2JdbcTemplate); // 異常,分母不能為零
 int num = 1/0;
}123456789復(fù)制代碼類型:[java]

我們添加了@Transactional注解,按照正常的思路來說兩個數(shù)據(jù)庫中都不應(yīng)該有數(shù)據(jù)加入:  

SpringBoot整合分布式事務(wù)

數(shù)據(jù)庫Family確實沒有數(shù)據(jù)加入:  

SpringBoot整合分布式事務(wù)

但是Family2卻有數(shù)據(jù)加入:  

SpringBoot整合分布式事務(wù)

這是不符合邏輯的,因為數(shù)據(jù)庫事物不能跨鏈接,數(shù)據(jù)源更不能跨庫。如果出現(xiàn)了上述操作那這個事務(wù)就變成了分布式事務(wù),需要一個統(tǒng)一協(xié)調(diào)的管理器。所以我們要解決這個問題。  

JTA實現(xiàn)跨庫分布式事務(wù)  

XA規(guī)范:是一個兩階段提交協(xié)議(同時對數(shù)據(jù)進行處理),被很多數(shù)據(jù)庫和中間件支持。  

兩階段提交協(xié)議(2PC):將整個事務(wù)分成準(zhǔn)備階段和提交階段兩個階段。2指是兩個階段,P(Prepare),C(Commit)。  

正常情況下:  

準(zhǔn)備階段:事務(wù)管理器(TM)給Family和Family2發(fā)送Prepare消息,F(xiàn)amily和Family2在本地執(zhí)行事務(wù),寫本地的Undo/Redo日志,但是此時事務(wù)沒有提交。  

提交階段:事務(wù)管理器(TM)收到Family和Family2超時或執(zhí)行失敗的消息時,會對Family和Family2發(fā)送回滾消息。如果事務(wù)管理器沒有收到關(guān)于失敗的消息,就會發(fā)送提交消息。完成回滾或是提交之后需要釋放事務(wù)處理過程中使用的鎖資源。  

成功情況:  

SpringBoot整合分布式事務(wù)

失敗情況:  

SpringBoot整合分布式事務(wù)

兩階段提交是在數(shù)據(jù)庫層面實現(xiàn)的,下面我們來結(jié)合Family和Family2出現(xiàn)的問題進行解析。  

SpringBoot整合分布式事務(wù)

現(xiàn)在我們的應(yīng)用程序持有Family和Family2兩個數(shù)據(jù)庫,應(yīng)用程序通過事務(wù)管理器同時通知Family,F(xiàn)amily2添加數(shù)據(jù)。事務(wù)管理器收到執(zhí)行的回復(fù),兩個數(shù)據(jù)庫有一方失敗,就向另一方發(fā)起回滾事務(wù)?;貪L完畢,資源鎖釋放。如果都是成功,此時向所有數(shù)據(jù)庫發(fā)起提交事務(wù),提交完畢,資源鎖釋放。  

XA規(guī)范缺點:  

同步阻塞,數(shù)據(jù)庫鎖定資源時間太長,全局鎖,并發(fā)低,不適合長事務(wù)場景,還需要本地數(shù)據(jù)庫支持XA規(guī)范。  

JTA規(guī)范:可以理解為XA規(guī)范的Java版本。  

Atomikos:分布式事務(wù)管理器,JTA/XA的具體實現(xiàn)。(支持分布式事務(wù),單獨引入了事物管理器導(dǎo)致性能開銷大,不適合用于高并發(fā)場景)  

分布式事務(wù)就是跨數(shù)據(jù)庫對數(shù)據(jù)進行操作的事務(wù),要達到的目的是要么都成功,要么都失敗。  

首先我們在pom.xml文件中引入atomikos依賴包:  

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>1234復(fù)制代碼類型:[java]

之后我們需要對application.yml進行修改:  

server:
  port: 8888spring:
  jackson:
 date-format: yyyy-MM-dd HH:mm:ss
 time-zone: GMT+8

  datasource:
 familydb:
   uniqueResourceName: family
   xaDataSourceClassName: com.mysql.cj.jdbc.MysqlXADataSource
   xaProperties:
  url: jdbc:mysql://localhost:3306/Family?serverTimezone=GMT%2b8&characterEncoding=utf-8
  username: root
  password: 123456
   exclusiveConnectionMode: true
   minPoolSize: 5
   maxPoolSize: 15
   testQuery: SELECT 1 from dual
 family2db:
   uniqueResourceName: family2
   xaDataSourceClassName: com.mysql.cj.jdbc.MysqlXADataSource
   xaProperties:
  url: jdbc:mysql://localhost:3306/Family2?serverTimezone=GMT%2b8&characterEncoding=utf-8
  username: root
  password: 123456
   exclusiveConnectionMode: true
   minPoolSize: 5
   maxPoolSize: 15
   testQuery: SELECT 1 from dual12345678910111213141516171819202122232425262728293031復(fù)制代碼類型:[java]

現(xiàn)在再來改寫一下DataSourceConfig.java:  

@Configurationpublic class DataSourceConfig { // JTA數(shù)據(jù)源family
 @Bean
 @Primary
 @ConfigurationProperties(prefix = "familydb")
 public DataSource familyDataSource() {  // 返回AtomikosDataSourceBean,配置屬性也都是注入到這個類里面
  return new AtomikosDataSourceBean();
 } // JTA數(shù)據(jù)源family2
 @Bean
 @ConfigurationProperties(prefix = "family2db")
 public DataSource family2DataSource()  {  return new AtomikosDataSourceBean();
 } // familyJdbcTemplate使用familyDataSource數(shù)據(jù)源
 @Bean
 public JdbcTemplate familyJdbcTemplate(   @Qualifier("familyDataSource") DataSource familyDataSource) {  return new JdbcTemplate(familyDataSource);
 } // family2JdbcTemplate使用family2DataSource數(shù)據(jù)源
 @Bean
 public JdbcTemplate family2JdbcTemplate(   @Qualifier("family2DataSource") DataSource family2DataSource) {  return new JdbcTemplate(family2DataSource);
 }
}1234567891011121314151617181920212223242526272829303132復(fù)制代碼類型:[java]

將上述代碼改寫完成后,在config文件下創(chuàng)建TransactionManagerConfig.java:  

package com.javafamily.familydemo.config;import com.atomikos.icatch.jta.UserTransactionImp;import com.atomikos.icatch.jta.UserTransactionManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.DependsOn;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.jta.JtaTransactionManager;import javax.transaction.SystemException;import javax.transaction.TransactionManager;import javax.transaction.UserTransaction;@Configurationpublic class TransactionManagerConfig { @Bean
 public UserTransaction userTransaction() throws SystemException {
  UserTransactionImp userTransactionImp = new UserTransactionImp();
  userTransactionImp.setTransactionTimeout(10000);  return userTransactionImp;
 } @Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
 public TransactionManager atomikosTransactionManager() throws Throwable {
  UserTransactionManager userTransactionManager = new UserTransactionManager();
  userTransactionManager.setForceShutdown(false);  return userTransactionManager;
 } @Bean(name = "transactionManager")
 @DependsOn({"userTransaction", "atomikosTransactionManager"})
 public PlatformTransactionManager transactionManager() throws Throwable {
  UserTransaction userTransaction = userTransaction();

  JtaTransactionManager manager = new JtaTransactionManager(userTransaction, atomikosTransactionManager());  return manager;
 }
}1234567891011121314151617181920212223242526272829303132333435363738394041復(fù)制代碼類型:[java]

以上的代碼屬于事務(wù)管理器配置,事務(wù)管理器負(fù)責(zé)協(xié)調(diào)多個JTA數(shù)據(jù)源實現(xiàn)事務(wù)機制,這是固定的寫法,不需要糾結(jié)。  

完成了以上的配置之后,我們再次驗證分母為零的異常問題:  

SpringBoot整合分布式事務(wù)

報出異常后,查看分別查看兩個數(shù)據(jù)庫:  

SpringBoot整合分布式事務(wù)

SpringBoot整合分布式事務(wù)

兩個數(shù)據(jù)庫由于異常都沒有數(shù)據(jù)被插入,問題解決!  

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多