spring声明式事务@Transactional的那些坑

本文探讨了Spring声明式事务管理中的一些关键属性,包括事务传播级别、隔离级别、超时和只读属性,以及回滚规则。通过实例解析了容易遇到的问题,如事务在方法调用中的传播行为,如何避免事务不当配置导致的问题,并提醒在有多个数据源时需要注意指定数据源。
摘要由CSDN通过智能技术生成

事务有四大特性,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),把这四大特性的英文首字母拼起来,就是ACID,这个单词对应的中文意思是“酸”,什么东西比较酸呢,柠檬(🍋),把它们联系起来,就容易记着这几个特性了。

在MySQL数据库中,默认的存储引擎Innodb是支持事务的,另一个比较常用的存储引擎MyISAM是不支持事务的。

插曲说一下,一直对MyISAM怎么读比较纠结,我查了一下,在mysql的邮件列表,有人问过这个问题,提到比较多的读法是 [My-I-sam],有相同困惑的朋友可以借鉴一下。

这四个特性的具体含义,这里就不再细说了,我们焦点放在在实际的编程中怎么避免踩坑。

声明式事务的属性

spring对事务的支持有两种方式:编程式事务和声明式事务。编程式事务对代码有侵入性,用起来也比较繁琐,一般也很少使用,声明式事务通过添加 @Transactional 注解来支持,事务的属性会添加在注解上。
声明式事务的几个属性需要了解。

事务传播级别

  1. TransactionDefinition.PROPAGATION_REQUIRED

@Transactional 注解默认的传播方式就是REQUIRED,在该传播模式下,如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

  1. TransactionDefinition.PROPAGATION_SUPPORTS

表示如果有事务,就加入到当前事务,如果没有,那也不开启事务执行。这种传播级别可用于查询方法,因为SELECT语句既可以在事务内执行,也可以不需要事务;

  1. TransactionDefinition.PROPAGATION_MANDATORY

表示必须要存在当前事务并加入执行,否则将抛出异常。这种传播级别可用于核心更新逻辑,比如用户余额变更,它总是被其他事务方法调用,不能直接由非事务方法调用;

  1. TransactionDefinition.PROPAGATION_REQUIRES_NEW

表示不管当前有没有事务,都必须开启一个新的事务执行。如果当前已经有事务,那么当前事务会挂起,等新事务完成后,再恢复执行;

  1. TransactionDefinition.PROPAGATION_NOT_SUPPORTED

表示不支持事务,如果当前有事务,那么当前事务会挂起,等这个方法执行完成后,再恢复执行;

  1. TransactionDefinition.PROPAGATION_NEVER

不支持事务,而且在检测到当前有事务时,会抛出异常拒绝执行;

  1. TransactionDefinition.PROPAGATION_NESTED

表示如果当前有事务,则开启一个嵌套级别事务,如果当前没有事务,则开启一个新事务。

事务隔离级别

在 org.springframework.transaction.annotation.Isolation 枚举中定义了@Transactional支持的隔离级别:

  • DEFAULT 使用数据库指定的隔离级别
  • READ_UNCOMMITTED 读未提交
  • READ_COMMITTED 读已提交
  • REPEATABLE_READ 可重复读
  • SERIALIZABLE 可串行化

超时属性

一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒,默认值为-1。-1代表使用底层事务系统默认的超时时间。

只读属性

对于只有读取数据查询的事务,可以指定事务类型为 readonly,即只读事务。只读事务不涉及数据的修改,数据库会提供一些优化手段,适合用在有多条数据库查询操作的方法中。
可以通过下面的语句查询数据库是否开启了自动提交,如果开启了,默认一条语句就是一个事务。


                
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值