Closed HasonHuang closed 4 years ago
这里是不能够修改成required的,事务日志会记录 可能/已经 与远程发生交互的接口。
如果回滚掉了这些信息的话,就在crash recovery的时候,没有办法获得哪些已经执行过,也就没办法调用crash场景下的cancel
感谢回复,我看见事务参与者是在钩子的 afterCompletion
阶段异步触发,如果在这阶段之前 crash 或回滚,是否表示参与者一定没有被触发?
以TCC为例,afterCompletion这部分触发的是Cancel或者Confirm操作,TRY操作会在事务过程中就被触发了
回滚时,为了消除TRY可能已经执行的影响,所以必须记录下哪些TRY可能被调用过了,然后调用其对应Cancel方法
问题
原因
DataBaseTransactionLogWritterImpl
时使用PROPAGATION_REQUIRES_NEW
传播级别,创建事务日志时无法与主事务使用同一个事务。DatabaseExtensionsSuiteConfiguration
和DataBaseTransactionLogConfiguration
创建DataBaseTransactionLogWritterImpl
时都是使用 EasyTrans 创建的数据源,导致创建日志时无法与主事务使用同一个事务。为什么可以优化
DataBaseTransactionLogWritterImpl
创建日志记录时,在beforeCommit
与主事务之间是同步操作(同一个线程),如果使用用户程序的数据源,可以与主事务的使用同一个事务管理。DataBaseTransactionLogWritterImpl#appendTransLog
没有在afterCompletion
和afterCommit
中执行。DataBaseTransactionLogWritterImpl#appendTransLog
除了第 1 点的情况,其他执行场景与用户事务(主事务)无关,不会因为用户事务回滚导致无法正常完成事务。DataBaseTransactionLogWritterImpl#cleanFinishedLogs
由一个异步线程执行。