美文网首页
Java事务以及嵌套事务

Java事务以及嵌套事务

作者: 程序员Anthony | 来源:发表于2019-09-29 21:24 被阅读0次

最近遇到事务的处理,嵌套事务,自己研究,整理一下。

1 先看结论

1、在Java事务中,事务的嵌套,如果有事务成功,那么则都成功,否则都不会成功。
2、如果事务中存在异常,只要对异常进行捕获和处理,都为执行成功,否则都不会执行成功。

2 Propagation取值

REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction;

SUPPORTS:如当前有transaction,则在transaction状态下执行;如果当前没有transaction,在无transaction状态下执行;

MANDATORY:必须在有transaction状态下执行,如果当前没有transaction,则抛出异常IllegalTransactionStateException;

REQUIRES_NEW:创建新的transaction并执行;如果当前已有transaction,则将当前transaction挂起;

NOT_SUPPORTED:在无transaction状态下执行;如果当前已有transaction,则将当前transaction挂起;

NEVER:在无transaction状态下执行;如果当前已有transaction,则抛出异常IllegalTransactionStateException。

3 预设场景

这里直接测试spring boot 使用spring data jpa添加一个用户进行测试

实体类user

@Data
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private long id;

    private String userName;

    public User(String userName) {
        this.userName = userName;
    }
}

UserRepository类

@Repository
public interface UserRepository extends CrudRepository<User,Long> {
}

UserService类

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;
}

4 实际场景使用

4.1 场景:并性事务

并行事务:
A:方法事务为默认的REQUIRED
B:方法事务为 REQUIRES_NEW 或者 REQUIRED


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;

    @Test
    public void test1() {
        userService.addUser1(new User("user1"));
        userService.addUser2(new User("user2"));
    }
}

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;

    @Transactional(rollbackFor = Exception.class)
    public void addUser1(User user) {
        userRepository.save(user);
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void addUser2(User user) {
        userRepository.save(user);
        throw new RuntimeException();
    }

}

执行结果:
保存了user1.

结论:并行事务不存在事务影响

4.2 场景:嵌套相同事务

a) 事务嵌套,在同一个事务中,没有对异常进行处理


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;

    @Test
    public void test2() {
        userService.addUser3();
    }

}

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;


    @Transactional(rollbackFor = Exception.class)
    public void addUser3() {
        userRepository.save(new User("user3"));
        this.addUser4(new User("user4"));

    }

    @Transactional(rollbackFor = Exception.class)
    public void addUser4(User user) {
        userRepository.save(user);
        throw new RuntimeException();
    }

}

执行结果:两个都没有插入成功

结论:由于两个都是在一个事务当中,所以只要有一个方法事务有问题,那么都不会插入成功。

b) 事务嵌套,在同一个事务中,对异常进行处理


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;

    @Test
    public void test3() {
        userService.addUser5();
    }


}

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;


    @Transactional(rollbackFor = Exception.class)
    public void addUser5() {
        userRepository.save(new User("user5"));
        this.addUser6(new User("user6"));
    }

    @Transactional(rollbackFor = Exception.class)
    public void addUser6(User user) {
        userRepository.save(user);
        try {
            throw new RuntimeException();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

执行结果:两个都插入成功。
 结论:如果事务存在异常,并进行捕获处理,不会影响事务。

4.3 场景:嵌套不同事务

a)事务嵌套,在不同事务中,没有对异常进行处理


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;

    @Test
    public void test4() {
        userService.addUser7();
    }

}

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;


    @Transactional(rollbackFor = Exception.class)
    public void addUser7() {
        userRepository.save(new User("user7"));
        this.addUser8(new User("user8"));
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void addUser8(User user) {
        userRepository.save(user);
      throw new RuntimeException();
    }
}

执行结果:都没有插入成功。
 结论:不同事务中,嵌套的事务,没有对异常进行处理,都不会执行成功。(其实在外部事务中出错,两个也是都不会插入成功数据。)

b)事务嵌套,在不同事务中,对异常进行处理


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    UserService userService;

    @Test
    public void test5() {
        userService.addUser9();
    }

}

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;



    @Transactional(rollbackFor = Exception.class)
    public void addUser9() {
        userRepository.save(new User("user9"));
        this.addUser10(new User("user10"));
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void addUser10(User user) {
        userRepository.save(user);
        try {
            throw new RuntimeException();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

执行结果:都插入成功。
 结论:不同事务,只要对异常进行捕获并处理,都会执行成功

相关文章

  • Java事务以及嵌套事务

    最近遇到事务的处理,嵌套事务,自己研究,整理一下。 1 先看结论 1、在Java事务中,事务的嵌套,如果有事务成功...

  • 面前温习

    Spring事务传播特性的浅析——事务方法嵌套调用的迷茫 解惑 spring 嵌套事务

  • Spring事务传播性和隔离机制

    1.Spring事务传播性 在事务出现嵌套的时候,嵌套的事务是各自独立commit,还是内层的事务合并到外层的事务...

  • java事务

    1、java事务介绍 2、JDBC事务 3、JTA事务 1、java事务介绍 java事务分类:JDBC事务、...

  • java中数据库事务嵌套与mysql事务隔离级别

    原文链接: java中数据库事务嵌套与mysql事务隔离级别 今天在java代码中遇到一个数据库相关的bug,在分...

  • Spring事务的传播属性和事务隔离级别

    事务的嵌套概念 所谓事务的嵌套就是两个事务方法之间相互调用。spring事务开启 ,或者是基于接口的或者是基于类的...

  • 事务的传播机制

    事务的嵌套概念 所谓事务的嵌套就是两个事务方法之间相互调用。spring事务开启 ,或者是基于接口的或者是基于类的...

  • 事务的传播机制和回滚策略(暂时没有整理完)

    事务的嵌套概念 所谓事务的嵌套就是两个事务方法之间相互调用。spring事务开启 ,或者是基于接口的或者是基于类的...

  • Spring嵌套事物

    一、事务传播机制: 事务的传播行为是针对嵌套事务而言。 示例: @Transactional(propagatio...

  • 精华总结

    1. laravel中事务嵌套事务会怎么样? 在MySQL的官方文档中有明确的说明不支持嵌套事务,但是在larav...

网友评论

      本文标题:Java事务以及嵌套事务

      本文链接:https://www.haomeiwen.com/subject/nbdqpctx.html