Spring 事务有几个隔离级别? Spring 有哪几种事务传播行为? Spring 事务传播行为有什么用?

Spring事务的隔离级别

在数据库操作中,多个事务并发执行时可能会出现诸如脏读、不可重复读、幻读等问题,事务隔离级别就是用来解决这些问题的,Spring 支持的事务隔离级别和数据库的事务隔离级别相对应,主要有以下几种:

1. ISOLATION_DEFAULT(默认隔离级别)
  • 含义:使用底层数据库默认的事务隔离级别。不同数据库默认隔离级别不同,例如 MySQL 的默认隔离级别是 REPEATABLE_READ ,Oracle 的默认隔离级别是 READ_COMMITTED
  • 特点:这种方式会根据具体使用的数据库来决定事务隔离的效果,开发人员无需手动指定具体隔离级别,方便快捷,但缺乏一定的可控性。
2. ISOLATION_READ_UNCOMMITTED(读未提交)
  • 含义:一个事务可以读取另一个未提交事务的数据。这是隔离级别最低的情况,几乎不做任何隔离控制。
  • 特点:存在脏读(一个事务读取到另一个事务未提交的数据)、不可重复读(在一个事务内,多次读取同一数据,结果却不同)、幻读(在一个事务内,多次执行相同的查询,结果集却不同)等问题 。但这种隔离级别下,事务之间的并发性能最高,因为几乎没有加锁等操作来限制并发。
3. ISOLATION_READ_COMMITTED(读已提交)
  • 含义:一个事务只能读取另一个已经提交事务的数据。
  • 特点:可以避免脏读问题,但仍然可能出现不可重复读和幻读问题。相比 ISOLATION_READ_UNCOMMITTED,它增加了一定的隔离性,在大多数数据库中,这是一种比较常用的隔离级别,在一定程度上平衡了并发性能和数据一致性。
4. ISOLATION_REPEATABLE_READ(可重复读)
  • 含义:在一个事务内,多次读取同一数据时,读取到的结果是一致的,即使在这个事务执行期间,其他事务对该数据进行了修改并提交。
  • 特点:可以避免脏读和不可重复读问题,但在某些情况下(如插入操作),可能还是会出现幻读问题。MySQL 的默认隔离级别就是可重复读,并且通过 MVCC(多版本并发控制)等机制,在很大程度上避免了幻读问题,是一种比较可靠的隔离级别 。
5. ISOLATION_SERIALIZABLE(可串行化)
  • 含义:最高级别的隔离级别,事务串行执行,一个事务执行完之后,另一个事务才开始执行。
  • 特点:可以完全避免脏读、不可重复读和幻读问题,保证了数据的绝对一致性。但由于事务只能串行执行,并发性能最差,会极大地降低系统的并发处理能力,一般在对数据一致性要求极高且并发量不大的场景下才会使用。

Spring事务的传播行为

事务传播行为是指当一个事务方法被另一个事务方法调用时,该如何传播事务,Spring 定义了 7 种事务传播行为:

1. PROPAGATION_REQUIRED(required,默认传播行为)
  • 含义:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • 示例:方法 A 没有事务,方法 B 被方法 A 调用,且方法 B 的事务传播行为是 PROPAGATION_REQUIRED,那么方法 B 会创建一个新事务;若方法 A 本身存在事务,方法 B 就加入到方法 A 的事务中,两者共同构成一个事务,要么都成功提交,要么都回滚。
2. PROPAGATION_SUPPORTS(supports)
  • 含义:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行。
  • 示例:方法 A 没有事务,方法 B 被方法 A 调用,方法 B 以非事务方式执行;若方法 A 存在事务,方法 B 就加入到方法 A 的事务中。
3. PROPAGATION_MANDATORY(mandatory)
  • 含义:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • 示例:方法 B 要求必须在一个事务环境下执行,当被方法 A 调用时,如果方法 A 没有事务,调用方法 B 就会抛出异常,只有方法 A 存在事务时,方法 B 才会加入到该事务中。
4. PROPAGATION_REQUIRES_NEW(requires_new)
  • 含义:创建一个新的事务,如果当前存在事务,则把当前事务挂起,等新事务执行完毕后,再恢复当前事务。
  • 示例:方法 A 有事务,方法 B 的事务传播行为是 PROPAGATION_REQUIRES_NEW,当方法 A 调用方法 B 时,方法 B 会创建一个新事务独立执行,方法 A 的事务会被挂起,方法 B 执行完成后,方法 A 的事务才继续执行,两个事务相互独立,各自有自己的提交和回滚操作。
5. PROPAGATION_NOT_SUPPORTED(not_supported)
  • 含义:以非事务方式执行操作,如果当前存在事务,则把当前事务挂起。
  • 示例:方法 A 有事务,方法 B 的事务传播行为是 PROPAGATION_NOT_SUPPORTED,当方法 A 调用方法 B 时,方法 B 会以非事务方式执行,方法 A 的事务被挂起,等方法 B 执行完毕后,方法 A 的事务再继续执行。
6. PROPAGATION_NEVER(never)
  • 含义:以非事务方式执行,如果当前存在事务,则抛出异常。
  • 示例:方法 B 不允许在事务环境下执行,当被方法 A 调用时,如果方法 A 存在事务,调用方法 B 就会抛出异常。
7. PROPAGATION_NESTED(nested)
  • 含义:如果当前存在事务,则创建一个事务嵌套在当前事务中执行;如果当前没有事务,则与 PROPAGATION_REQUIRED 一样,创建一个新事务。嵌套事务是一个独立的事务单元,可以单独回滚,但是当外层事务回滚时,内层事务也会回滚。
  • 示例:方法 A 有事务,方法 B 的事务传播行为是 PROPAGATION_NESTED,当方法 A 调用方法 B 时,方法 B 会创建一个嵌套事务,方法 B 可以单独提交或回滚,不影响方法 A 的事务,但是如果方法 A 回滚,方法 B 也会跟着回滚。

Spring事务传播行为的作用

  • 满足复杂业务场景需求:在实际的业务开发中,存在各种复杂的调用关系和事务需求。例如,在一个电商系统中,订单创建方法可能会调用库存扣减方法、支付方法等,不同的方法对事务的要求不同。通过事务传播行为,可以灵活地配置每个方法的事务处理方式,确保业务逻辑的正确性和数据的一致性 。
  • 提高系统的并发性能和资源利用率:合理地使用事务传播行为,可以避免不必要的事务开销,提高系统的并发性能。比如,对于一些只读操作的方法,使用 PROPAGATION_SUPPORTS 或者以非事务方式执行,可以减少事务锁的竞争,提高系统的并发处理能力。
  • 增强代码的可维护性和可扩展性:事务传播行为将事务的管理从业务逻辑中分离出来,通过配置的方式来决定事务的处理方式。这样在代码的维护和扩展过程中,只需要修改事务传播行为的配置,而不需要修改业务逻辑代码,降低了代码的耦合度,提高了代码的可维护性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值