-
Notifications
You must be signed in to change notification settings - Fork 8
Home
本框架是为了解决金融/电商系统的分布式最终一致性而设计。比传统的XA的两阶段提交,和1pc(1阶段最大努力型)有明显的优势,但是使用起来有一定的门槛,并不是所有的公司都适用。关于xa 两阶段,1pc,tcc的介绍文章 分布式事务典型处理方式
通过一个账号充值例子,对比1pc和tcc的区别
一阶段最大努力型: 虽然一阶段有提交,也有回滚。跟tcc 还是有本质的区别。 以账户系统为例,给张三充值: 一阶段最大努力型:update set account = acount +x, 回滚操作 Update set account = account -x . 这里有问题风险:先充值成功,后面才回滚,存在两个风险。1 充值的钱被提现。 2 回滚存在失败的情况。 这种情况在高危的金融领域是不允许的。
**Tcc ** 预留必要的资源:以给张三充值为例。Try:往充值的流水的预处理表插入一条记录。 在confirm 阶段,才将该记录插入到流水表,并且账户表加钱。 Cancel 阶段将删除充值的流水的预处理表的记录。 而且confirm阶段如果失败,会不停的重复提交,直到成功。只需要一个事务id(uuid)保证幂等性即可。因为在插入的时候,通过唯一性索引保持,不需要使用额外的uuid表。
本框架的核心思想源自支付宝的tcc框架。以xid(分布式事务id)贯穿整个tcc的try,commit,rollback. 使用这种设计的优点
- xid由业务自定义生成,可以在xid生成的时候加入业务分库分表的等属性,方便后续业务横向扩展。
- commit/rollback方法参数非常简单,简单到只需要一个xid参数。考虑到框架未来的扩展性,增加了TccContext作为commit/rollback的第二个参数. 提升序列化的性能。
通过一个简单的电商例子作为tcc框架的使用demo。
demo-itemcenter 商品中心。服务启动:demo-itemcenter/demo-itemcenter.deploy com.touna.tcc.demo.itemcenter.deploy.Bootstrap
demo-pay 支付中心。服务启动:demo-pay/demo-pay.deploy com.touna.tcc.demo.pay.deploy.Bootstrap demo-trading 交易中心.
db/tcc.sql tcc框架初始化sql。
db/demo.sql tcc框架demo初始化sql。
测试用例:src/test/com/touna/tcc/demo/trading/service
OrderServiceTest (模拟下单,商品库存减1,账号余额减1)
PerformanceTest (100线程并发测试,验证框架多线程线程安全处理)
ToleranceTest (容错测试,模拟5组常见异常)
运行测试用例之前,1 需要初始化数据库(tcc-demo/db/tcc.sql tcc框架自带表,tcc-demo/db/demo.sql tcc运行demo程序需要的表),2 启动demo-pay服务,demo-itemcenter服务。
tcc框架核心包。核心包定义了抽象的接口,抽象类,方便业务定制和扩展。
TccTransactionInterceptor tcc分布式事务拦截器
AbstractTransactionManager 事务管理器抽象类。
log包 事务序列化
tcc dubbo 框架适配器。
DubboTransactionManager dubbo 事务管理器(extends AbstractTransactionManager)
TccTransactionFilter dubbo consumer 过滤器
tcc 事务补偿程序。
- sql初始化(tcc-demo/db/tcc.sql)
- 项目maven pom需要依赖tcc的jar(可以将github源码下载,部署到私服)
<dependency> <groupId>com.touna</groupId> <artifactId>tcc-dubbo</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
spring 需要定义tcc的bean
<bean id="tccTransactionInterceptor" class="com.touna.tcc.core.interceptor.TccTransactionInterceptor" >
<property name="txLogService" ref="txLogService"></property>
<property name="transactionManagerBeanName" value="tccTransaction"/>
</bean>
<!--bean id tccTransaction 不能更改-->
<bean id="tccTransaction" class="com.touna.tcc.dubbo.transaction.DubboTransactionManager">
<!--tcc commit/rollback 方法序列化分配空间(字节数)。分配大小依据TccContext的大小。
如果TccContext都没用上,设置128足够-->
<constructor-arg value="1024"/>
<property name="txLogService" ref="txLogService"></property>
<property name="txChildLogService" ref="txChildLogService"></property>
</bean>
<import resource="classpath:config/tcc-core-service.xml"/>
3 dubbo consumer配置。业务节点的资源文件配置 resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter 配置(参考 tcc-demo/demo-pay)
4. 代码嵌入tcc注解
4.1 dubbo facade(api) 定义。
一个tcc的try方法,需要带一个commit方法和rollback方法。commit和rollback方法名在try方法的@TwoPhaseBusinessAction注解里面定义。
> @TwoPhaseBusinessAction(commitMethod="payCommit",rollbackMethod="payRollback")
> void pay(String xid,@Attachment(key="accountId") String accountId,Double amount);
> Boolean payCommit(String xid,TccContext tccContext);
> Boolean payRollback(String xid,TccContext tccContext);
使用规范:
1 try方法,第一个参数需要xid,如果需要将try的参数传递到TccContext,通过@Attachment实现(扩展功能)。
2 commit/rollback 方法必须是2个参数,第一个参数是xid,第二个参数是TccContext tccContext
3 commit/rollback 方法返回值必须是Boolean, 返回true表示执行成功,返回false,表示执行失败。
4 主程序调用facade(try阶段) 如果发现facade返回业务异常,需要抛exception
4.2 分布式事务使用tcc @Resource AccountFacade accountFacade;
@Resource
ItemFacade itemFacade;
@Override
@TccTransactional(xidIndex = 0)
@Transactional()
public void placeOrder(String xid,String accountId,String productId,Double price) {
accountFacade.pay(xid, accountId, price);
itemFacade.sell(xid, productId, 1);
}
使用规范:1.xid(分布式事务id)由用户生成,传递给方法体。2.需要在方法体上加上 @TccTransactional(xidIndex = 0) ,其中xidIndex = 0表示,xid为方法体的第n个参数。
单元测试
@Test
public void testPlaceOrder(){
String xid = XidGenerator.getNewXid("OD");
orderService.placeOrder(xid, "1", "1", 1.00);
}
#测试tcc框架 tcc-demo里面有各种测试用例。方便了解tcc框架执行结果。测试用例的时候,可以通过tcc_tx,tcc_tx_child 查看事务的状态。
tcc事务状态:0 :begin,1:finish,2:try success,3 try fail,4:confirm fail,5:rollback fail。 参考com.touna.tcc.core.transaction.XaState定义