1. 相关知识
CPA定理BASE及分布式数据一致算法
C:数据一致 A:高可用 P:分区容错
只能实现AP和CP,C和A只能选其一
cap中常用的数据一致性算法:raft(领导选举,自选收回应心跳)、paxos
分布式事务的几种解决方案
2PC (刚性事务)-遵循ACID原则,强一致性 业务使用率低,seata 属于2pc,高并发模式下不适用,比如:生成订单及支付
TCC (柔性事务 )– BASE原则,最终一致性,商城用的多,需要自己写回归逻辑和事务补偿
最大努力通知方案 (柔性事务 ) 案例:银行、支付宝等
可靠消息+最终一致性方案(柔性事务 )
2.事务失效问题
默认情况下spring的事务分很多种和数据库的级别性质差不多
spring的是我默认是需要新的事务,
例如:如果同一个类中a方法添加了默认事务,b方法也是默认的事务,c方法时新的事务(此处的事务是设置的事务的传播性),
如果a方法中调用了b和c,那么b和c方法就会共同a方法的事务,c的事务就失效了,
原因是:同一个事务方法互相调用默认失效,绕过了代理对象,事务使用代理对象来控制的
解决: 时候用代理对象调用事务的方法,也就是b和c
- 引入aop-starter 因为其中引入了aspectj
- 在启动类上@EnableAspectJAutoProxy 开启aspectj动态代理,以后动态代理都是aspectj创建的(既是没有接口,也可以创建动态代理)
- 设置属性(@EnableAspectJAutoProxy(exposeProxy = true)) 对外暴露代理对象
- 用代理对象实现本类互相调用
原来的写法
@Transactional(timeout=30)
void a(){
b();
c(); //c的事务会失效,变成a的事务
}
@Transactional(propagation = Propagation.REQUIRED,timeout=10)
//次事务的传播性是默认的,会跟从调用者的事务
void b(){
}
@Transactional(propagation = Propagation.REQUIRES_NEW,timeout=20)
//此事务是只遵循自己的新事务,不尊徐调用者事务
void c(){
}
新的写法
@Transactional(timeout=30)
void a(){
SpuInfoServiceImpl spuInfoService = (SpuInfoServiceImpl) AopContext.currentProxy();
spuInfoService.b();
spuInfoService.c(); //这样c事务就不会跟从a的事务
}