springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實現(xiàn)
背景
我們平時在用springboot開發(fā)時,要使用事務(wù),只需要在方法上添加@Transaction注解即可,但這種方式只適用單數(shù)據(jù)源,在多數(shù)據(jù)源下就不再適用;
比如在多數(shù)據(jù)源下,我們在一個方法里執(zhí)行了數(shù)據(jù)源A的操作,又執(zhí)行了數(shù)據(jù)源B的操作,如果報錯了,事務(wù)只會回滾主數(shù)據(jù)源或者是指定事務(wù)的數(shù)據(jù)源數(shù)據(jù)(@Transactional(value="指定事務(wù)")),另一個數(shù)據(jù)源是不會回滾的;
這種情況下,單純的@Transactional事務(wù)注解是無法實現(xiàn)的,此時就需要用到多數(shù)據(jù)源事務(wù)管理;
以下項目里實現(xiàn)了普通情況下的事務(wù)處理和使用springboot-jta-atomikos事務(wù)處理
本文主要介紹使用springboot-jta-atomikos來實現(xiàn);
源碼地址
https://github.com/lvlq73/springboot-jta-atomikos
項目目錄結(jié)構(gòu)

實現(xiàn)
1.添加依賴 pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>2.配置數(shù)據(jù)庫連接信息 application.properties
#atomikos測試 spring.datasource.test1.url=jdbc:mysql://127.0.0.1:3306/test1?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai spring.datasource.test1.user=root spring.datasource.test1.password=arsenal spring.datasource.test2.url=jdbc:mysql://127.0.0.1:3306/test2?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai spring.datasource.test2.user=root spring.datasource.test2.password=arsenal
3.創(chuàng)建多數(shù)據(jù)源 DBAtomikosConfig.java
package com.llq.atomikos.config;
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.jta.JtaTransactionManager;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;
import java.util.Properties;
/**
* @author lvlianqi
* @description
* @date 2022/3/7
*/
@Configuration
public class DBAtomikosConfig {
//--------------------數(shù)據(jù)源1--------------------
@ConfigurationProperties(prefix = "spring.datasource.test1")
@Bean
public Properties testOneProperties() {
return new Properties();
}
@Bean(name = "testOneDataSource")
@Primary
public DataSource testOneDataSource() {
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
Properties prop = testOneProperties();
ds.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
ds.setUniqueResourceName("testOne");
ds.setXaProperties(prop);
return ds;
}
@Bean
@Primary
public JdbcTemplate testOneJdbcTemplate(@Qualifier("testOneDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
//--------------------數(shù)據(jù)源2--------------------
@ConfigurationProperties(prefix = "spring.datasource.test2")
@Bean
public Properties testTwoProperties() {
return new Properties();
}
@Bean(name = "testTwoDataSource")
public DataSource testTwoDataSource() {
AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
Properties prop = testTwoProperties();
ds.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
ds.setUniqueResourceName("testTwo");
ds.setXaProperties(prop);
return ds;
}
@Bean
public JdbcTemplate testTwoJdbcTemplate(@Qualifier("testTwoDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
//--------------------配置spring的JtaTransactionManager,底層委派給atomikos進行處理--------------------
@Bean
public JtaTransactionManager jtaTransactionManager () {
UserTransactionManager userTransactionManager = new UserTransactionManager();
UserTransaction userTransaction = new UserTransactionImp();
return new JtaTransactionManager(userTransaction, userTransactionManager);
}
}
4.測試事務(wù)類 TestAtomikos.java
package com.llq.atomikos.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author lvlianqi
* @description
* @date 2022/3/7
*/
@Service
public class TestAtomikos implements ITest{
@Qualifier("testOneJdbcTemplate")
@Autowired
private JdbcTemplate testOneJdbcTemplate;
@Qualifier("testTwoJdbcTemplate")
@Autowired
private JdbcTemplate testTwoJdbcTemplate;
/**
* 測試正常情況
*/
@Transactional(rollbackFor = Exception.class, value = "jtaTransactionManager")
public void test() {
testOneJdbcTemplate.execute("insert into user (name, age) values ('張三', 18);");
testTwoJdbcTemplate.execute("insert into user (name, age) values ('李四', 20);");
}
/**
* 測試異常情況
*/
@Transactional(rollbackFor = Exception.class, value = "jtaTransactionManager")
public void testByException() {
testOneJdbcTemplate.execute("insert into user (name, age) values ('張三', 18);");
testTwoJdbcTemplate.execute("insert into user (name, age) values ('李四', 20);");
int i = 1/0;
}
}
5.測試 SpringbootAtomikosApplicationTests.java
//使用atomikos
private static Class CLS = TestAtomikos.class;
@Autowired
ApplicationContext applicationContext;
@Test
public void testByException() {
ITest test = (ITest) applicationContext.getBean(CLS);
test.testByException();
}
測試結(jié)果
執(zhí)行錯誤

數(shù)據(jù)庫test1 user表沒有記錄

數(shù)據(jù)庫test2 user表沒有記記錄

到此這篇關(guān)于springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實現(xiàn)的文章就介紹到這了,更多相關(guān)springboot 多數(shù)據(jù)源事務(wù)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot+springmvc實現(xiàn)登錄攔截
這篇文章主要介紹了springboot+springmvc實現(xiàn)登錄攔截,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-10-10
java+SpringBoot設(shè)計實現(xiàn)評教系統(tǒng)
這篇文章主要介紹了用過Java SpringBoot實現(xiàn)一個簡單的評價系統(tǒng),可以做到學(xué)生管理、教師管理、評教管理、指標(biāo)管理、課程管理等。感興趣的可以了解一下2021-12-12
基于SpringBoot生成二維碼的幾種實現(xiàn)方式
本文將基于Spring Boot介紹兩種生成二維碼的實現(xiàn)方式,一種是基于Google開發(fā)工具包,另一種是基于Hutool來實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2022-03-03
Spring?BeanDefinition父子關(guān)系示例解析
這篇文章主要為大家介紹了Spring?BeanDefinition父子關(guān)系示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
Java 使用openoffice進行word轉(zhuǎn)換為pdf的方法步驟
這篇文章主要介紹了Java 使用openoffice進行word轉(zhuǎn)換為pdf的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

