0
点赞
收藏
分享

微信扫一扫

本地事务的简要小结

诗尚凝寒 2022-04-23 阅读 70
javaspring

1、事务的基本性质

数据库事务的四个特性——ACID(可通过【acid:酸的】来记忆):
原子性(Atomicity):一系列的操作要么同时成功,要么同时失败;
一致性(Consistency):数据在事务的前后,业务整体一致;
隔离性(Isolation):事务之间互相隔离;
持久性(Durabilily):一旦事务成功,数据的更改是永久性的。

一个事务开始,代表这个事务内的所有操作的在同一个连接里。

2、事务的隔离级别(从小到大)

1)READ UNCOMMITTED(读未提交)
该隔离级别的事务会又脏读现象:指读到其它未提交事务的数据。 

2)READ COMMITTED(读提交)
——Oracle 和 SQL Server 的默认隔离级别
会导致不可重复读现象:指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。

3)REPEATABLE READ(可重复读)
—— MySQL 默认的隔离级别
在同一个事务里,查询所得的数据是事务刚开始时的状态,所以读到的结果会是一致的。但会产生幻读现象。MySQL的 InnoDB 引擎可以通过 next-key locks 机制来避免幻读。

4)SERIALIZABLE(序列化)
在该隔离级别下事务都是串行顺序执行的。
MySQL 数据库的 InnoDB 引擎会给读操作隐式加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。

3、事务的传播行为

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 类似的操作。

4、本地事务失效问题

同一个对象内事务方法互调默认失效,因为这种操作绕过了代理对象。
解决:
使用代理对象来调用事务方法
1)引入aop-starter:引入了AspectJ

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2)@EnableAspectJAutoProxy(exposeProxy = true):开启aspectj动态代理功能。对外暴露代理对象。示例:

public class TestService {
    //本类方法调用
    @Transactional(timeout = 20)
    public void a(){
        TestService testService = (TestService) AopContext.currentProxy();
        testService.b();
        testService.c();
    }
    @Transactional(propagation = Propagation.REQUIRED,timeout = 5)
    public void b(){
        
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW,timeout = 10)
    public void c(){
        
    }
}
举报

相关推荐

0 条评论