我们先复习一下本地事务
1.本地事务
数据库事务的几个特性:
原子性(Atomicity),一致性(Consistency),持久性(Durabilily),隔离性(Isolation)
原子性:一系列的操作整体不可拆分,同时成功同时失败
一致性: 数据在事务前后,业务整体一致
隔离性:事务之间互相隔离
持久性:一旦事务成功,数据一定会落盘在数据库
1.1.事务的隔离级别
读未提交 READ UNCOMMITTED:
该隔离级别的事务会读到其他未提交事务的数据,此现象为脏读
读已提交 READ COMMITTED:
一个事务可以读取另一个已提交的事务,多次读取会造成不一样的结果,此现象称为不可重复读(Oracle默认)
可重复读 REPEATAVBLE READ:
该隔离级别是mysql默认级别,在同一个事务里,select的结果是事务开始时间间点的状态,因此,同一的
select操作读到的结果会是一致的,但是,会有幻读现象。
mysql的innodb引擎可以通过next-key locks机制来避免幻读
序列化 SERIALIZABLE:
在该隔离级别下事务都是串行执行的,mysqk数据库的innodb引擎会给读操作隐式加一把共享锁,从而避免了脏读,幻读和不可重复读问题。
1.2.事务传播行为
1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,常用。
2.PROPAGATION_SUPPORTS:支持当前的事务,如果当前存在事务,就加入该事务,如果当前不存在事务,
就以非事务方式执行。
3.PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛异常
4.PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,就抛出异常。
7.PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,
则执行与(PROPAGATION_REQUIRED 事务一样的操作)。
举例
@Transactional(propagation = Propagation.REQUIRED)
public void a(){
b();
c();
}
@Transactional(propagation = Propagation.REQUIRED)
public void b(){
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void c(){
}
这三个方法中都使用了事务,并且a调用了b,c两个方法,a,b两个方法使用的是同一种传播行为
情况1:
如果在a方法发生了异常,进行了回滚,那么b也会回滚,但是c不会回滚。
情况2:
如果b方法发送了异常,进行了回滚,那么a方法也会进行回滚,但是c不会回滚
情况3:
如果c方法发生了异常,进行了回滚,那么a,b方法都不会回滚。
1.3.超时时间
@Transactional(propagation = Propagation.REQUIRED,timeout = 30)
public void a(){
b();
c();
}
@Transactional(propagation = Propagation.REQUIRED,timeout = 5)
public void b(){
}
@Transactional(propagation = Propagation.REQUIRED_NEW,timeout = 10)
public void c(){
}
这里设置了超时时间,标识事务30秒没有执行完返回,则就回滚
那么都设置了超时时间以哪个准呢?
说明:
a方法:首先a方法肯定是30秒事务没有返回就回滚。
b方法:而b方法的事务的传播行为原因,导致和a方法共用一个事务,所以也是30秒。
c方法:由于事务的传播行为不同,所以c方法和a,b都是相同的事务,所以是10秒
1.4.事务的坑

本文探讨了分布式事务的背景和挑战,分析了CAP定理与BASE理论,介绍了强一致性、弱一致性和最终一致性。文章详细阐述了2PC、Seata等分布式事务解决方案,并讨论了各自的优缺点。此外,还提到了柔性事务,如TCC、最大努力通知型和可靠消息+最终一致性方案,特别关注了在实现这些方案中可能遇到的消息丢失、重复和积压问题。
最低0.47元/天 解锁文章
305

被折叠的 条评论
为什么被折叠?



