spring 事务隔离级别、传播机制、失效场景

16 篇文章 0 订阅

隔离级别

在这里插入图片描述
DEFAULT:这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是:READ_COMMITTED。
READ_UNCOMMITTED:该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。
READ_COMMITTED:该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
REPEATABLE_READ:该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。
SERIALIZABLE:所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

用法:

@Transactional(isolation = Isolation.DEFAULT)

传播机制

在这里插入图片描述
REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于REQUIRED。

用法:

@Transactional(propagation = Propagation.REQUIRED)

失效场景

原理

Spring事务是通过代理方式实现,有两种:
版本2.0之前,基于接口的JDK动态代理,要求目标代理类需要实现一个接口才能被代理
版本2.0之后,基于实现目标类子类的CGLIB代理

1.数据库引擎不支持事务

这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB。

2.没有被 Spring 管理
// @Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}

事务所在类对象没有被spring管理,无法实现子类代理,所以无法支持事务

3.方法不是 public 的或者是final的

非public和final方法无法实现子类代理

4.类内部调用this
@Service
public class OrderServiceImpl implements OrderService {
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}

事务的管理是通过代理执行的方式生效的,如果是方法内部调用,将不会走代理逻辑,也就调用不到了

5.事务的传播行为影响
@Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void update(Order order) {
        updateOrder(order);
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateOrder(Order order) {
        // update order
    }
}

update 方法上加了 @Transactional,updateOrder 加了 REQUIRES_NEW 新开启一个事务,那么新开的事务抛异常老的事务不会回滚

6.异常被捕获
@Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch { 
        }
    }
}

把异常捕获,然后又不抛出来,事务不会回滚

7.异常类型错误
 @Service
public class OrderServiceImpl implements OrderService {
    @Transactional
    public void updateOrder(Order order) {
        try {
            // update order
        } catch {
            throw new Exception("更新错误");
        }
    }
}

这样事务也是不生效的,因为默认回滚的是:RuntimeException,如果你想触发其他异常的回滚,需要在注解上配置一下,如:@Transactional(rollbackFor = Exception.class)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
事务隔离级别是指多个事务并发执行时,一个事务对其他事务的可见性和影响程度的控制。Spring框架支持四个事务隔离级别: 1. 未提交读(READ UNCOMMITTED):最低级别,一个事务可以读取未提交的数据,会导致脏读,不可重复读和幻读问题的出现。 2. 提交读(READ COMMITTED):一个事务只能读取已提交的数据,可以避免脏读问题,但可能导致不可重复读和幻读问题。 3. 可重复读(REPEATABLE READ):在一个事务中多次读取同一数据时,结果保持一致,避免了不可重复读问题。但仍然可能存在幻读问题。 4. 串行化(SERIALIZABLE):最高级别,通过确保事务串行执行来避免脏读、不可重复读和幻读问题。但会降低并发性能。 传播机制是指在调用多个事务方法时,如何处理事务传播。Spring框架提供七种传播行为: 1. REQUIRED:如果当前没有事务,就创建一个新事务;如果已存在事务,则加入该事务。 2. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方法执行。 3. MANDATORY:强制要求存在当前事务,如果没有事务就抛出异常。 4. REQUIRES_NEW:创建一个新事务,并暂停当前事务(如果有)。 5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将其挂起。 6. NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。 7. NESTED:在当前事务的控制下执行一个嵌套事务,如果不存在当前事务,则创建一个新事务。嵌套事务可以独立提交或回滚,但在外部事务提交时才会生效。 通过选择合适的事务隔离级别传播机制,可以确保事务的数据一致性、安全性和性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值