mysql多数据源事务_Spring,Mybastis,,Mysql多数据源事务不回滚的问题解决

本文介绍了在Spring、Mybatis环境中遇到的多数据源事务问题及其解决方案。包括@Transactional注解在内部方法调用时失效,MySQL MyISAM引擎不支持事务,以及Spring默认只对运行时异常进行回滚的处理。针对多数据源事务回滚问题,提出了使用JTA(Java Transaction API)和Atomikos实现跨数据源事务控制的策略,并展示了相关配置示例。
摘要由CSDN通过智能技术生成

因为架构升级,导致同样的功能在两套完全的里的系统中分别提供,又因为不能完全切换,所以系统1.0和系统2.0的数据要做到同步,所以为实现数据一致性,所以开发了一套数据同步系统,涉及到了多个数据源,调试过程中有数据异常导致的部分数据没有插入成功,但是存在数据没有回滚的情况。

1、本类调用@Transactional注解的方法事务不其中用,因为采用Spring的注解方式(aop)实现事务控制,aop的实现无论是使用动态代理还是织入方式都是通过对业务类包装实现的,当内部方法调用时,不会使用包装类的实现,所以不会引入事务,如下代码所示:

[pre]

[code lang=”java”]

public class TransactionInvoker {

private TrancationCallee trancationCallee;

/**

*

* @Title testNotTransaction

* @Description 事务没有作用

*

*/

public void testNotTransaction() {

trancationCallee.notTrancation();

}

/**

*

* @Title testTransaction

* @Description 事务有作用

*

*/

public void testTransaction() {

trancationCallee.trancaction();

}

}

public class TrancationCallee {

public void notTrancation() {

this.trancaction();

}

@Transactional

public void trancaction() {

}

}

[/code]

[/pre]

2、部分数据库引擎不支持事务,比如Mysql的Myisam引擎。

检查表引擎是否支持,mysql查询创建语句:

show create table 表名;

可以从建表语句上查看该表的数据库引擎

3、Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked

如果遇到checked意外就不回滚。

如何改变默认规则:

a、让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

b、让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

4、多数据源事务回滚,Spring的默认事务控制,只能绑定一个数据源,因此当多个数据数据源时,同时配置多个事务控制只有一个会有作用,因此当异常触发回滚时,只回滚第一个事务配置绑定的数据源的sql,没有实现多数据源的异常回滚。

解决办法,使用JTA可以实现多数据源的事务控制,但是大多数JTA需要使用JNDI,需要应用服务器(tomcat)等上做配置。atomikos提供了在应用中配置实现JTA事务控制的方法。

涉及改动的配置如下:

数据源的配置:

[pre]

[code lang=”xml”]

${jdbc_url}

${jdbc_username}

${jdbc_password}

[/code]

[/pre]

事务配置:

[pre]

[code lang=”xml”]

false

[/code]

[/pre]

其他的配置保持不变:

[pre]

[code lang=”xml”]

[/code]

[/pre]

记得在开启注解扫描和需要事务的方法上添加@Transactional

好的,关于Spring Boot多数据源的实现,可以通过配置多个数据源并在需要使用的时候进行切换。在Spring Boot中,可以通过使用注解来声明多个数据源,并使用特定的注解来标识当前使用的数据源。 下面是一个简单的例子: 首先在application.properties文件中配置多个数据源: ``` # 数据源1 spring.datasource.url=jdbc:mysql://localhost:3306/datasource1 spring.datasource.username=root spring.datasource.password=123456 # 数据源2 spring.datasource.datasource2.url=jdbc:mysql://localhost:3306/datasource2 spring.datasource.datasource2.username=root spring.datasource.datasource2.password=123456 ``` 然后,在需要使用数据源的地方,使用@Primary注解来标识默认的数据源,使用@Qualifier注解来指定使用哪个数据源: ``` @Service public class UserServiceImpl implements UserService { @Autowired @Qualifier("datasource1") // 指定使用datasource1数据源 private DataSource dataSource; @Autowired @Qualifier("datasource2") // 指定使用datasource2数据源 private DataSource dataSource2; @Autowired private JdbcTemplate jdbcTemplate; @Autowired @Qualifier("transactionManager") // 指定使用事务管理器 private PlatformTransactionManager transactionManager; @Override @Transactional public void addUser(User user) { // 使用默认数据源 jdbcTemplate.update("insert into user(name, age) values(?, ?)", user.getName(), user.getAge()); // 切换数据源 TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) { JdbcTemplate jdbcTemplate2 = new JdbcTemplate(dataSource2); jdbcTemplate2.update("insert into user(name, age) values(?, ?)", user.getName(), user.getAge()); } }); } } ``` 在上面的例子中,我们使用了JdbcTemplate来操作数据库,并且在需要使用不同数据源的时候,使用@Qualifier注解来指定具体的数据源。同时,在需要进行事务管理的地方,使用了Spring声明式事务,并且通过注入PlatformTransactionManager来指定使用哪个事务管理器。 希望这个例子能够帮助你理解Spring Boot多数据源的实现方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值