分布式消息与数据库事务共享模式

Posted 力奋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式消息与数据库事务共享模式相关的知识,希望对你有一定的参考价值。

事务管理器org.springframework.jdbc.datasource.DataSourceTransactionManager(AbstractPlatformTransactionManager).getTransaction创建ConnectionHolder并用DriverManagerDataSource对象作键值保存在TransactionSynchronizationManager.resources.使TransactionSynchronizationManager.isSynchronizationActive=true表示可以执行TransactionSynchronizationManager.registerSynchronization保存事务对应的同步器到synchronizations如JmsResourceSynchronization。在事务使用JmsTemplate方法首先会创建JmsResourceHolder并用ActiveMQConnectionFactor对象作键值保存在TransactionSynchronizationManager.resources,同一个事务内共用session和connection。
ActiveMQSession.createConsumer()方法创建连接MQ服务器的消费者对象,MQ服务器会把消费者要操作的消息队列锁住,其它消费者对象不能操作这个消息队列,其它生产者对象可进行写操作,执行MessageConsumer.close()才释放锁。然后JmsTemplate.doReceive()方法是读取MQ服务器的消息,读取消息只是被MQ服务器隔离,执行session.commit()后MQ服务器才最终删除读取消息。不执行session.commit()消息可以回滚。代码片段下图,表示如果session由DataSourceTransactionManager管理可以忽略执行session.commit(),等到执行事务方法DataSourceTransactionManager.commit()再执行。同步器JmsResourceSynchronization已注册到TransactionSynchronizationManager,DataSourceTransactionManager.commit()会触发TransactionSynchronizationManager.synchronizations里所有同步器的afterCommit()方法,如JmsResourceSynchronization.afterCommit(),最终执行session.commit()。
            if (session.getTransacted()) {
                // Commit necessary - but avoid commit call within a JTA transaction.
                if (isSessionLocallyTransacted(session)) {
                    // Transacted session created by this template -> commit.
                    JmsUtils.commitIfNecessary(session);
                }
            }

 

 
 

以上是关于分布式消息与数据库事务共享模式的主要内容,如果未能解决你的问题,请参考以下文章

分布式事务| 使用 dotnetcore/CAP 的本地消息表模式

分布式事务| 使用 dotnetcore/CAP 的本地消息表模式

架构模式: 事务发件箱

分布式事务性消息原理与实践

RabbitMQ解决分布式事务

RocketMQ(消息重发重复消费事务消息模式)