Spring事务
事务是逻辑处理原子性的保证手段,通过事务的控制,可以极大地避免出现逻辑失败导致的脏数据问题。
事务两个重要的特性,事务的传播和隔离级别。传播定义了事务的控制范围,而隔离级别定义了事务在数据库读写方面的控制范围。
Spring事务传播机制
七种传播方式。
REQUIRED
。Spring默认的事务传播级别。如果上下文已经存在事务,那么就加入到事务中执行,如果上下文不存在事务,则新建事务执行,子方法也会运行在同一个事务中。这个级别能够满足大多数业务场景。SUPPORTS
。如果上下文存在事务,则加入事务,如果没有事务,则不使用事务。MANDATORY
。要求上下文必须存在事务,否则抛出异常。这种配置方式,有效控制了上下文调用代码遗漏添加事务控制的保证手段。比如一段代码不能单独被调用执行,一旦被调用,就必须有事务包含的情况,就可以使用该传播级别。REQUIRES_NEW
。如果当前有事务,则挂起该事务,并且自己创建一个新的事务给自己使用;如果没有,则新建一个事务。这是一个很好用的传播级别,举个应用场景:要发送100个红包,在发送之前,要做系统的初始化,验证,数据记录操作,然后发送100封红包,再记录发送记录,发送日志要求100%的准确,如果日志不准确,整个父事务逻辑需要回滚。使用REQUIRES_NEW
就可以完成,发送红包的子事务不会直接影响父事务的提交和回滚。NOT_SUPPORTED
。不支持事务,如果当前上下文有事务,则挂起事务,执行当前逻辑,执行完之后恢复上下文事务。这个传播级别,可以帮助把事务的范围缩小。例如,每次逻辑的操作,都要调用一个循环多次的的非核心业务的逻辑操作,把这样的代码加入到事务中,肯定会造成事务范围太多,容易出现难以预测的异常情况。NEVER
。不允许上下文存在事务,一旦有事务,就抛出runtime异常,强制停止执行。NESTED
。嵌套事务。如果上下文存在事务,则嵌套事务执行,如果不存在,则新建。
使用@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
注解来为方法指定传播机制。
Spring事务隔离级别
Serializable
:最严格的级别,事务串行执行。Repeatable Read
:可重复读,保证一个事务不会修改另一个事务读取但是未提交的数据。避免了”脏读”和”不可重复读”的情况。Read Committed
:大多数主流数据库的默认事务级别。保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了”脏读”。Read UnCommitted
:未提交读。保证了读取过程不会读到非法的数据,避免了”更新丢失”。