spring事务和@Transactional

简单用谁都会,但是会有复杂的用法的。

1.使用注意

1.1只针对public方法

1.2 关于propagation属性

  1. TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  2. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  3. TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

1.3 rollbackFor

默认情况下, 抛出运行时异常就回滚。 可以自定义一个异常才回滚。

@Transactional(propagation= Propagation.REQUIRED,rollbackFor= MyException.class)

1.4 isolation 事务隔离等级

配置说明
READ_UNCOMMITTED读取未提交数据(会出现脏读, 不可重复读) 基本不使用
READ_COMMITTED读取已提交数据(会出现不可重复读和幻读)
REPEATABLE_READ可重复读(会出现幻读)
SERIALIZABLE串行化 (一个个来,效率最低可是最安全)
  • MYSQL: 默认为REPEATABLE_READ级别
  • SQLSERVER: 默认为READ_COMMITTED

并发update、删除的情况下,事务设置串行化好

1.5 递归调用,@Transactional会忽略

demo:

# 下面的方式,事务不起效

@Service
public class OrderService {
    private void insert() {
        insertOrder();
    }

    @Transactional
    public void insertOrder() {
        //insert log info
        //insertOrder
        //updateAccount
       }
}

要在外部调用insertOrder() 方法,事务才生效。毕竟是AOP。

2. 原理和源码

下图说明流程:

待补充


Comments

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注