官网: https://www.codingapi.com/docs/home/
原理:
来着官网
使用:
一个eureka。
一个TM,两个RM,分别为订单服务和支付服务。
具体详细配置请访问官网。
订单服务Controller:
@PostMapping("/add-order")
@Transactional(rollbackFor = Exception.class)
@LcnTransaction
public String add(@RequestBody TblOrder bean){
JSONObject date = new JSONObject();
date.put("payName",bean.getOrderName()+"pay");
restTemplate.postForEntity("http://lcn-pay/add-pay",date,String.class);
int i = 1/0;
tblOrderDao.insert(bean);
return "新增订单成功";
}
支付服务Controller:
@PostMapping("/add-pay")
@Transactional(rollbackFor = Exception.class)
@LcnTransaction
public String addPay(@RequestBody TblPay bean){
tblPayDao.insert(bean);
// int i = 1/0;
return "新增支付成功";
}
加上@LcnTransaction即可
源码
1 入口:
使用了aop切面类拦截
TransactionAspect
获取事务消息:
执行过程:
判断是否有事务上下文
有就获取获取父上下文
没有就创建
并判断是否为事务发起者
将上下文信息放到缓存中,
点进去是个Map<String, Object> singlePropCache
一般框架有什么startxx
大部分都会有
endXX
clearXX
cleanXX
destoryXX
代码往下拉一拉:
发现销毁方法
执行完在finally里删除上下文信息
获取到上下文信息之后,设置一堆参数,巴拉巴拉,进入到关键点:
DTXServiceExecutor # transactionRunning
获取事务传播状态
开始事务操作
pre 预执行
事务发起者初始化事务组
事务参与者没执行啥
业务执行
就是执行@LcnTransaction注解修饰的方法的内容
执行完成功:
事务发起方:
将状态设为1
事务参与方:
加入到事务组
执行完失败:
事务发起方:
将状态设为0
事务参与方:
删除事务信息
执行完毕:
通知TM
往里面点点点:
2 LCN如何获取操作数据库连接的?
DataSourceAspect
获取数据库连接时拦截:
进行代理,对不同类型的事务的数据库连接进行自己的包装
以LCN为例:
返回的是自己的数据亏连接代理类:
做一些自己的处理
大致过程差不多就这样
有空再看看TCC模式的
感兴趣可一起探讨