分布式几种方式:TCC、CC、XA等
tcc是分布式中的最终一致性解决方案,就是牺牲强一致性,满足最终结果的一致性解决方案。
主要使用示例:
/**
* 在此处通过rpc接口调用,调用用户余额以及库存接口,实现:扣除余额以及减少库存量
* 在此处定义confirm 以及 cancel方法
* @param order 订单实体
*/
@Override
@Hmily(confirmMethod = "confirmOrderStatus", cancelMethod = "cancelOrderStatus")
public void makePayment(Order order) {
//保存订单之后,执行此操作;设置支付状态为支付中---2
order.setStatus(OrderStatusEnum.PAYING.getCode());
orderMapper.update(order);
整个tcc的核心就是在所有改变状态或者需要进行补偿的地方(方法上)添加确认以及取消的方法,如此处时保存订单状态为支付中,如果该方法提交成功就执行confirm方法,进行确认操作:
public void confirmOrderStatus(Order order) {
order.setStatus(OrderStatusEnum.PAY_SUCCESS.getCode());
orderMapper.update(order);
LOGGER.info("=========进行订单confirm操作完成================");
}
此处确认成功就是修改状态为支付成功,
如果方法执行失败,就执行cancel方法:
public void cancelOrderStatus(Order order) {
order.setStatus(OrderStatusEnum.PAY_FAIL.getCode());
orderMapper.update(order);
LOGGER.info("=========进行订单cancel操作完成================");
}
修改状态为支付失败,以此方法进行补偿。
可以根据是事务的发起者还是参与者进行特定操作,以下提供一种通过数据库进行分布式事务的思路:
1.首先通过rpc调用时,可以获取到达当前系统之前系统的ThreadLocal,因为事务发起者是在之前平台,而当前平台为参与者。因此可以把当前事务的transId通过rpc传入到当前系统,然后保存该事务的具体信息,存放到数据库或者其他地方。
举例:如果是订单-转账-库存系统,对应三个数据库,然后还有一个数据库,存放三个数据库(三个系统)每次操作时的调用方法及其成功以及失败的方法 信息,便于后期提交或者确认。然后定时任务定时刷新数据库,如果成功就提交,然后把冻结或者说是保留的数据进行最终的更新,否则就进行回滚。
但是部分系统的事务成功,但是事务的发起者失败这种情况如果出现,不知该如何解决一致性问题。保留一种思路就是根据数据库的事务发起者判断,如果失败,就通过事务id查找对应的所有事务进行回滚,只要有记录就回滚(在单独的数据库里),成功后就删除对应的信息。也可以通过redis等存储事务信息
核心就是aop反射调用,同时协调一致性的保持是主要,以及通过rpc获取前一个系统的事务信息等。
rpc调用时,可以继承Filter,调用invoke()方法,只要是rpc调用都会调用此invoke方法,同时可以判断调用是否成功,(这么说可以在一个系统进行判断)。