前言
回到master-1.2.x分支,继续浏览git log,在1.0.3版本后,作者更新较为频繁,每个月都有提交,在2016/6/4日有一次版本变更1.1.0,但是不要急,根据这段时间文件变更内容看,东西修改了不少,但是1.1.0之后还有几次频繁修改,包括几个issue的修订。
最后我确定从issue#22的修复为模板,拉取分支(afterv1.1.0-resolvesTheIssue22),go on。
正文
主要功能模块
tcc-transaction-api
增加了UuidUtils:工具类,uuid与byte[]互转
tcc-transaction-core
core模块结构
- common包,包含MethodType和TransactionType,之前就有,换了下位置。
- interceptor包,包含CompensableTransactionInterceptor和ResourceCoordinatorInterceptor,简单看内容,是将之前sping下的两个aop拆解出来,放到core模块。
- recover包,事务补偿相关,不在本次分析内。
- repository包,持久化相关,增加了很多,如FileSystem、Jdbc、Redis、Zookeeper,而CachableTransactionRepository是作为基类存在。
- serializer包,序列化相关,包含JDK和Kryo两种方式。
- support包,BeanFactory及其适配器类BeanFactoryAdapter、事务配置接口TransactionConfigurator。
- utils包,工具包,其中CompensableMethodUtils内容为重点。
其他类:
- 细分了异常(CancellingException、ConfirmingException、NoExistedTransactionException、OptimisticLockException、SystemException),
- 核心注解Compensable,
- 将注解属性由字符串转换为可执行方法的一系列类:存储注解配置信息的InvocationContext,桥接类Participant,最终执行者Terminator
- 记录事务信息的Transaction、对事务信息进行CRUD操作的TransactionManager(这里的ConcurrentHashMap变更为ThreadLocal<Transaction>)
- 定义事务信息持久化操作的接口TransactionRepository
以上共同构成了框架的核心代码tcc-transaction-core模块。
tcc-transaction-spring
依然包含数据库脚本db.sql,其中几个字段类型由varchar变为varbinary,应该是通过api.UuidUtils实现的转换。
-
recover包,数据补偿操作,暂不关心。
-
repository包:只有SpringJdbcTransactionRepository,spring下的仓储方式,需要配置DataSource,在新增的测试模块tutorial-sample和单元测试模块unit-test有使用。
-
support包:与core模块中的support包呼应。
support内:
- TccApplicationContext实现BeanFactory、ApplicationContextAware,成员有ApplicationContext(set注入),getBean,用ApplicationContext获取bean。
- TccBeanPostProcessor实现ApplicationListener,重写onApplicationEvent在应用启动后获取ApplicationContext,再获取BeanFactory注入到BeanFactoryAdapter中。
- TccTransactionConfigurator实现TransactionConfigurator接口,实现了获取transactionManager、transactionRepository、recoverConfig三个方法。通过spring-xml注入。
其他类:
- TccCompensableAspect,通过spring-xml注入,其成员CompensableTransactionInterceptor通过set注入
- TccTransactionContextAspect,通过spring-xml注入,其成员ResourceCoordinatorInterceptor通过set注入
整体看来变化不大,关键点是两个aop类的结构变化,将核心代码转移到了core模块下。
tcc-transaction-tutorial-sample
这个模块下都是demo,目前有dubbo方式服务的集成例子,有时间再分析。
tcc-transaction-unit-test
结构基本没有变化,执行下org.mengyun.tcctransaction.unit.test.TransferServiceTest#testTransfer,看一下调用过程,观察每个节点数据变化。
结尾
这个版本看下来,更多是在进行整理,将模块职责划分清楚些。
另外,有一点是之前没思路上注意到的,就是org.mengyun.tcctransaction.unittest.client.AccountServiceProxy#transferTo(...)这个方法的实现,是通过多线程方式进行下级服务调用的,也就是通过多线程方式开启分支事务,应该是对应于TransactionManager中分支事务相关信息的缓存操作是记录在ThreadLocal<Transaction> threadLocalTransaction,也就是ROOT事务和分支事务是有独立的Transaction对象进行记录的,而且在ResourceCoordinatorInterceptor中需要将Participant“注册”到Transaction中,使用多线程就更加容易理解,由ThreadLocal独立存储Transaction,在不同线程中触发aop,不同方法封装不同的Participant,记录到Transaction中达到事务信息隔离。
还有一点,在进行单元测试时,最好将补偿流程的job注释掉,不然会干扰测试结果(主要是断点时间过长,数据就会出问题,什么问题可以自行验证)。