当前位置:首页 >系统运维 >MySQL和MongoDB事务同步的一种尝试 正文

MySQL和MongoDB事务同步的一种尝试

来源:益强资讯优选   作者:IT科技类资讯   时间:2025-11-05 11:19:35
现象

最近线上的事试一条数据状态不对,但是种尝日志又记录上了。 查看了这条数据的事试更新逻辑复制public Boolean autoReject(AutoRejectParam param) { OperationLog log = createOperationLog(param); // 保存操作日志到mysql operationLogMapper.insertSelective(log); Query query = new Query(); Criteria criteria = new Criteria(); criteria.and("requestId").is(param.getRequestId()); query.addCriteria(criteria); Update update = new Update(); update.set("status", CvBusinessStatusEnum.Rejected.getCode()) .set("updateTime", new Date()) .set("taskId", ""); mongoTemplate.updateFirst(query, update, JSONObject.class, collectionName); return true; }1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.

从代码可以看出这里分别保存了日志到mysql,然后更新了mongodb中的数据状态。

MySQL和MongoDB事务同步的一种尝试

很明显保存mysql成功了,种尝但是更新mongodb的数据失败了,那为什么保存mongodb的数据失败了呢? 然后根据日志发现,当时服务器和mongodb连接出现了问题,于是就导致了保存mysql成功,保存到mongodb失败了。事试

如何解决?种尝

问题既然产生了,那么有什么办法能够保证要成功就都成功呢?事试 第一个想到的是事务,我们需要保证两个数据库操作的事务一致性就可以避免这个问题了。使用单一的种尝事务管理器肯定是不行的,亿华云需要使用链式事务。事试

我们可以使用spring中的种尝ChainedTransactionManager来实现链式调用

复制@Configuration public class TransactionConfig { @Bean public PlatformTransactionManager mongoTransactionManager(MongoTemplate mongoTemplate) { return new MongoTransactionManager(mongoTemplate.getMongoDbFactory()); } @Bean public PlatformTransactionManager jpaTransactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean public ChainedTransactionManager chainedTransactionManager( PlatformTransactionManager mongoTransactionManager, PlatformTransactionManager jpaTransactionManager) { return new ChainedTransactionManager(mongoTransactionManager, jpaTransactionManager); } } @Transactional("chainedTransactionManager") public Boolean autoReject(AutoRejectParam param) { //省略其他代码 // 保存操作日志到mysql operationLogMapper.insertSelective(log); // 更新mongodb mongoTemplate.updateFirst(query, update, JSONObject.class, collectionName); return true; }1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.

这种方法使用 ChainedTransactionManager 来管理多个事务管理器。当方法执行时,事试它会按顺序开启所有事务,种尝如果在执行过程中出现异常,事试它会按相反的种尝顺序回滚所有事务。

需要注意的事试是,这种方法并不能保证 100% 的事务一致性,因为它实际上是在应用层面模拟的分布式事务。在某些极端情况下(比如网络故障或服务器崩溃),可能会出现部分提交的情况。

比如我们是现在这样的服务器租用执行流程

复制transaction1 begin transaction2 begin transaction2 commit -> error rollbacks, rollbacks transction1 too transaction1 commit -> error, only rollbacks transaction11.2.3.4.

比如上面这种情况,在最后提交transaction1的时候如果由于网络原因提交失败了,就会导致事务2成功,事务1失败,还是部分提交了。

当然如果业务要求对于这种不一致是可以接受的,或者说我们可以进行手动补偿方式达到最终一致性,那这种方案也是可以接受的。

对于要求更高事务一致性的场景,可能需要考虑使用专门的分布式事务解决方案,如 XA 协议或 TCC (Try-Confirm-Cancel) 模式。 比如JTA就属于XA协议, 我们可以使用开源实现atomikos。

企商汇

标签:

责任编辑:域名