事务传播机制
示例:
传播机制测试
@Override
public User testTransactional02() {
User user = new User();
user.setUsername("田所浩二");
user.setEmail("191919191919@.qq.com");
user.setPassword("78945613213");
user.setAdmin(false);
User insert = jpaServiceImpl.doSave(user);
insert.setTelephone("1919810124124");
User update = jpaServiceImpl.doUpdate(insert);
System.out.println("update: " + update.getId());
return update;
}
@Transactional(rollbackFor = RuntimeException.class, transactionManager = "transactionManager")
public User doSave(User user) {
return userRepository.save(user);
}
@Transactional(rollbackFor = RuntimeException.class, transactionManager = "transactionManager")
public User doUpdate(User user) {
userRepository.save(user);
throw new RuntimeException("抛个异常");
}
NESTED测试
JPA不支持NESTED传播机制
REQUIRES_NEW
@Override
@Transactional
public User testTransactional02() {
User user = new User();
user.setUsername("田所浩二");
user.setEmail("191919191919@.qq.com");
user.setPassword("78945613213");
user.setAdmin(false);
User insert = jpaServiceImpl.doSave(user);
insert.setTelephone("1919810124124");
User update = jpaServiceImpl.doUpdate(insert);
System.out.println("update: " + update.getId());
throw new RuntimeException("抛个异常");
}
@Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRES_NEW, transactionManager = "transactionManager")
public User doSave(User user) {
return userRepository.save(user);
}
@Transactional(rollbackFor = RuntimeException.class, transactionManager = "transactionManager")
public User doUpdate(User user) {
return userRepository.save(user);
}
结果:doSave()成功 + doUpdate()回滚。
由于doSave()的传播机制是REQUIRES_NEW,即在testTransactional02()的事务中doSave()也会分别新建一个事务,相当于不受testTransactional02()事务的控制。而doUpdate()是默认的传播机制REQUIRE,因为testTransactional02()的异常而连带回滚。
NOT_SUPPORTED
@Override
@Transactional
public User testTransactional02() {
User user = new User();
user.setUsername("田所浩二");
user.setEmail("191919191919@.qq.com");
user.setPassword("78945613213");
user.setAdmin(false);
User insert = jpaServiceImpl.doSave(user);
insert.setTelephone("1919810124124");
User update = jpaServiceImpl.doUpdate(insert);
System.out.println("update: " + update.getId());
throw new RuntimeException("抛个异常");
}
@Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.NOT_SUPPORTED, transactionManager = "transactionManager")
public User doSave(User user) {
return userRepository.save(user);
}
@Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.REQUIRES_NEW, transactionManager = "transactionManager")
public User doUpdate(User user) {
return userRepository.save(user);
}
结果:doSave()、doUpdate()成功执行、testTransactional02()抛异常。
因为doSave()不参与testTransactional02()的事务,doUpdate()也是新创建了一个事务,所以testTransactional02()抛异常不会影响这两个方法。
MANDATORY
@Override
public User testTransactional02() {
User user = new User();
user.setUsername("田所浩二");
user.setEmail("191919191919@.qq.com");
user.setPassword("78945613213");
user.setAdmin(false);
User insert = jpaServiceImpl.doSave(user);
insert.setTelephone("1919810124124");
User update = jpaServiceImpl.doUpdate(insert);
System.out.println("update: " + update.getId());
throw new RuntimeException("抛个异常");
}
@Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.MANDATORY, transactionManager = "transactionManager")
public User doSave(User user) {
return userRepository.save(user);
}
@Transactional(rollbackFor = RuntimeException.class, transactionManager = "transactionManager")
public User doUpdate(User user) {
return userRepository.save(user);
}
结果:doSave()方法直接报错,MANDATORY作为被调用方法时,调用方法必须存在事务。