作者:西西为考研要拼命啦 | 来源:互联网 | 2023-09-12 00:59
链接事务管理器(Chaining transaction managers)
在最大努力单阶段提交模式(Best Efforts 1PC pattern)的其他示范程序 (best-db-db
项目) 中,
一个事务管理器的原始实现只是把其它一些事务管理器链接起来以实现事务同步。如果业务处理成功,它们都提交,否则全部回滚。
具体实现在ChainedTransactionManager
中,接受一些其他的事务管理器作为注入的属性,如清单8所示:
列表8. ChainedTransactionManager的配置
要对这个配置进行简单的测试,只要插入一些数据到数据库中,回滚,并检查两个操作没有留下任何痕迹。这实现在MultipleDataSourceTests
的一个单元测试中,和XA模式中的atomikos-db项目相同。如果回滚不同步,但恰巧提交成功,则测试失败。
记住,资源的顺序很重要。它们是嵌套的,提交或回滚动作以与它们入列的顺序(在配置中的顺序)相反的顺序来执行。这使得其中一个资源是特殊的:如果有问题,最外层的资源总是被回滚,即使只有该资源失败。同时,testInsertWithCheckForDuplicates
()方法展示了一个幂等的业务流程防止系统出现部分失败。这被实现为在内部资源业务处理中的防范性检查(在这个案例中是otherDataSource
):
int count = otherJdbcTemplate.update("UPDATE T_AUDITS ... WHERE id=, ...?");if (count == 0) { count = otherJdbcTemplate.update("INSERT into T_AUDITS ...", ...);}
这个更新语句首先尝试WHERE子句。如果一切顺利,你希望寻找的数据会被成功插入。在这个案例中,正常情况下幂等处理的额外保护的成本是一个额外的查询(更新)。在一个更复杂的,每个事务都执行很多查询的业务过程中这个成本将低得多。
其它选择(Other options)
例子中的ChainedTransactionManager
has足够简单;它和许多可用的扩展和优化并不相干。另一种方法是使用Spring中的TransactionSychronization
API,为当前事务在第二个资源加入的时候注册一个回调。这是在best-jms-db示范项目中用到的方法,在那个例子中关键功能是把
TransactionAwareConnectionFactory和一个
DataSourceTransactionManager进行绑定
。这种特殊情况,可以扩大和推广到包括使用TransactionSynchronizationManager
的非JMS资源。原理上好处是,只有这些加入事务的资源会加入队列,而不是链中的所有资源。然而,配置仍然需要知道可能的事务中的参与者对应于哪个资源。
同时,Spring工程师团队正在考虑把“最大努力单阶段提交(Best Efforts 1PC)事务管理器”实现为Spring核心模块的一个功能。如果你喜欢这个模式,希望Spring对它有更明确的支持,你可以为这个任务的JIRA问题单(JIRA issue)投票。
by iefreer