事务

异常

notion image

事务失效的原因

事务在某些情况下可能不会按预期那样工作,以下是一些常见的原因:
  1. 子线程中的事务不会生效
      • 主线程中的事务对子线程是不可见的。
      • 子线程可以访问主线程中已经存在于内存中的值,例如事务中生成的对象ID。
      • 在子线程中尝试查询未提交事务中的数据可能会返回null,因为数据尚未被持久化到数据库中。
  1. 异常处理不当
      • 如果业务代码中的异常被try...catch语句捕获,并且没有通过throw new RuntimeException重新抛出,则事务不会回滚。
      • 这种情况是最难发现的,也是最容易被忽略的。
  1. 错误的事务传播行为配置
      • 使用@Transactional(propagation = Propagation.NOT_SUPPORTED)会导致事务不起作用。
      • 这种配置通常不是预期的行为,因此很少被使用。
  1. 不支持事务的存储引擎
      • 如果使用的MySQL存储引擎是MyISAM而不是InnoDB,则事务特性将不起作用。
  1. 非运行时异常
      • 如果业务代码抛出的是RuntimeException之外的异常,而这些异常又不在@TransactionalrollbackFor属性中声明,则事务不会回滚。
  1. 事务配置缺失或不正确
      • 比如未正确声明事务管理器或者@Transactional注解使用不当。

挂载事务提交之后处理

事务传播行为

事务传播行为描述了当一个事务方法调用另一个事务方法时,如何处理这些事务之间的关系。以下是几种不同的传播行为及其含义:
  1. Propagation.REQUIRED
      • 如果当前存在事务,则加入该事务;否则创建一个新的事务。
  1. Propagation.SUPPORTS
      • 如果当前存在事务,则加入该事务;否则以非事务的方式继续运行。
  1. Propagation.MANDATORY
      • 如果当前存在事务,则加入该事务;否则抛出异常。
  1. Propagation.REQUIRES_NEW
      • 创建一个新的事务,如果当前存在事务,则暂停当前的事务。
  1. Propagation.NOT_SUPPORTED
      • 以非事务的方式运行,如果当前存在事务,则暂停当前的事务。
  1. Propagation.NEVER
      • 以非事务的方式运行,如果当前存在事务,则抛出异常。
  1. Propagation.NESTED
      • 类似于Propagation.REQUIRED,但在支持嵌套事务的平台(如Hibernate)上,允许内部事务比外部事务更早地回滚。

事务的隔离级别

事务的隔离级别定义了事务之间数据的可见性和一致性。下面是四种主要的隔离级别,按照严格程度从高到低排列:
  1. SERIALIZABLE (序列化)
      • 所有事务依次执行,避免了所有并发问题,但也导致最低的并发性能。
  1. REPEATABLE_READ (可重复读)
      • 保证在一个事务中多次读取同一数据的结果相同,但不能防止“幻影读”。
  1. READ_COMMITTED (已提交读)
      • 可以读取其他事务提交的数据,但可能导致“不可重复读”。
  1. READ_UNCOMMITTED (未提交读)
      • 可以读取其他事务未提交的数据,可能导致“脏读”
Loading...
目录
文章列表
王小扬博客
产品
Think
Git
软件开发
计算机网络
CI
DB
设计
缓存
Docker
Node
操作系统
Java
大前端
Nestjs
其他
PHP