其他分享
首页 > 其他分享> > 3-Transactional中propagation属性

3-Transactional中propagation属性

作者:互联网

@Transactional注解中有很多的属性,但是大多数属性都是比较好理解的,当然除了这个propagation属性之外。

因为这个属性的值比较多,场景也比较多所以容易混淆和以往,这里就做下总结,方便以后进行复习。

虽然propagation中的值比较多,但是很多值都不常用,所以我分为两部分,一部分是常用的值,一部分是不常用的值。重点理解常用值,而非常用值面试时候使用。

propagation值

propagation的值 解释 是否常用
Propagation.REQUIRED
Propagation.SUPPORTS
Propagation.MANDATORY
Propagation.REQUIRES_NEW
Propagation.NOT_SUPPORTED
Propagation.NEVER
Propagation.NESTED

Propagation.REQUIRED

图中所指的开始事务的意思就是添加上@Transactional注解的意思。

由于同一个类中调用带有@Transactional的方法是无效的,所以我创建了两个方法来进行测试。先测试。

Case 1情况

在ServiceAImpl.class中创建一个带有@Transactional方法,分别执行添加操作和调用方法操作

    @Transactional
    @Override
    public void entranceHaveTransactional() {
        User user= User.builder()
                .id(20)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
        iServer.required();
        // 请注意这里,制造了一个人为的异常
        throw new RuntimeException("人为制造异常");
    }

在ServerImpl中创建一个方法required,并插入数据

    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public void required() {
        User user= User.builder()
                .id(5)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
    }

结果

这两个方法在同一个事务当中,由于entranceHaveTransactional方法抛出异常,所以两个方法的插入都没有生效,查看数据库也确实如此。

Case 2情况

    @Override
    public void entranceHaveTransactional() {
        User user= User.builder()
                .id(20)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
        iServer.required();
        // 请注意这里,制造了一个人为的异常
        throw new RuntimeException("人为制造异常");
    }
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public void required() {
        User user= User.builder()
                .id(5)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
        // 这里注意 新添加了一个异常
        throw new RuntimeException("required exception");
    }

执行结果

id为20插入数据库成功,而id为5的没有插入成功,说明和图示描述的逻辑一致。

Propagation.REQUIRES_NEW

Case 1情况

    @Transactional
    @Override
    public void entranceRequiredNew() {
        User user= User.builder()
                .id(21)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
        iServer.requiredNew();
        throw new RuntimeException("人为制造异常");
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    @Override
    public void requiredNew() {
        User user= User.builder()
                .id(6)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
    }

结果

id为6的数据成功插入到数据库,而id为21的的没有插入到数据库,和图示中Case 1 描述完全一致。

Case 2 情况

    @Override
    public void entranceRequiredNew() {
        User user= User.builder()
                .id(20)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
        iServer.requiredNew();
        throw new RuntimeException("人为制造异常");
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    @Override
    public void requiredNew() {
        User user= User.builder()
                .id(6)
                .passWord("122")
                .userName("hello")
                .realName("realname")
                .build();
        userMapper.insertOne(user);
        throw new RuntimeException("requiredNew");
    }

结果

id为21的数据成功插入到数据库中,而id为6的没有插入到数据库中。

说明requiredNew中的事务起了作用,而由于entranceRequiredNew没有添加事务,所以可以添加到书库中,异常不影响。

其他情况都比较少见,可以自行进行编写,进行查看。如果想看详细代码可以查看我github仓库,地址为:

https://github.com/bulingfeng/spring-cloud-demo/tree/master/spring-transactional-demo

注意事项

  1. 我每次测试都是把数据库中的数据进行删除,所以不存在主键冲突的情况。
  2. 我理解图示中的逻辑其实是主要取决于被调用方法所使用@Transactional中propagation的值,调用方法使用@Transactional代表是否开始事务(如有理解错误,请留言纠正)。

标签:Propagation,Transactional,propagation,user,属性,id,User
来源: https://www.cnblogs.com/bulingfeng/p/16416121.html