@Transactional事务传播
原始表数据
@Transactional()控制事务传播的配置项目(默认Propagation.REQUIRED)
@Transactional(propagation=Propagation.REQUIRED) //控制事务传播。默认是Propagation.REQUIRED
@Transactional(isolation=Isolation.DEFAULT) //控制事务隔离级别。默认跟数据库的隔离级别相同
@Transactional(readOnly=false) //控制事务可读写、只可读。默认可读写
@Transactional(timeout=30) //控制事务的超时时间,单位秒。默认跟数据库的事务控制系统相同
@Transactional(rollbackFor=RuntimeException.class) //控制事务遇到哪些异常会回滚。默认是RuntimeException
@Transactional(rollbackForClassName=RuntimeException) //同上
@Transactional(noRollbackFor=NullPointerException.class) //控制事务遇到哪些异常不会回滚。默认遇到RuntimeException回滚
@Transactional(noRollbackForClassName=NullPointerException)//同上
咱们此次就使用默认的@Transactional
注解,不添加任何参数。
并且不使用**try{}catch{}**捕获异常。
同类调用方法
同类A方法调用B方法
1. 同类A方法和B方法都有@Transactional
注解
@Service
public class A_Service {
@Resource
UserMapper userMapper;
@Transactional
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
B();
}
@Transactional
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
}
然后使用测试类测试方法
@SpringBootTest
public class TransactionalTest {
@Resource
A_Service a_Service;
@Test
public void test(){
a_Service.A();
}
}
运行结果
然后再看看数据库数据回滚没有
可以看到数据已经回滚
当同类A方法和B方法
@Transactional
注解,当A方法调用B方法时,B方法自己有事务,但是A方法也有事务,B方法就会加入A方法的事务里。所以在A、B任何地方发生异常都会进行回滚。
2. A方法有@Transactional
注解,B方法没有
修改B方法:
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
再次测试,然后再看看数据库数据回滚没有
当同类A方法
@Transactional
注解,当是B方法没有时,当A方法调用B方法时,A方法有事务,但B方法没有,B方法就会加入A方法的事务里。所以在A、B任何地方发生异常都会进行回滚。
3. A方法没有@Transactional
注解,B方法有@Transactional
注解
修改A方法
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
b_service.B();
}
再次测试,然后再看看数据库数据回滚没有
可以看到数据被A方法和B方法的都进行了修改。
说明当同类B方法被A方法调用时,B方法发现A方法没有事务。所以自己的事务也不会生效,所以两条SQL都没有进行回滚。
异类调用方法
A类A方法调用B类B方法
1. A类A方法和B类B方法都有@Transactional
注解
A类:
@Service
public class A_Service {
@Resource
UserMapper userMapper;
@Resource
B_Service b_service;
@Transactional
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
b_service.B();
}
}
B类:
@Service
public class B_Service {
@Resource
UserMapper userMapper;
@Transactional
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
}
然后使用测试类测试方法
@SpringBootTest
public class TransactionalTest {
@Resource
A_Service a_Service;
@Test
public void test(){
a_Service.A();
}
}
运行结果
然后再看看数据库数据回滚没有
可以看到数据已经回滚
当A类A方法和B类B方法
@Transactional
注解,当调用B类B方法时,B方法自己有事务,但是A方法也有事务,B方法就会加入A方法的事务里。所以在A、B任何地方发生异常都会进行回滚。
2. A类A方法有@Transactional
注解,B类B方法没有
修改B类B方法:
public void B(){
User user = new User();
user.setId(5);
user.setEmail("B");
userMapper.updateById(user);
throw new RuntimeException("B方法业务异常");
}
再次测试,然后再看看数据库数据回滚没有
可以看到数据已经回滚
当A类A方法有
@Transactional
注解,B类B方法没有。当A类A方法调用B类B方法时,B类B方法会加入A类A方法的事务。所以B类B方法报错,两个方法的SQL会全部回滚。
如果异常是在调用完B类B方法,在A类A方法或者B类B方法发生异常,事务都会进行回滚。
3. A类A方法没有@Transactional
注解,B类B方法有@Transactional
注解
修改A类A方法
public void A(){
User user = new User();
user.setId(5);
user.setEmail("A");
userMapper.updateById(user);
b_service.B();
}
再次测试,然后再看看数据库数据回滚没有
可以看到数据被A类A方法修改了,但是B类B方法的的数据回滚
说明当B类B方法被A类A方法调用时,B类B方法发现A类A方法没有事务,但是自己有事务就会创建事务,但是A类A方法依旧不会回滚。
如果异常是在调用完B类B方法,在A类A方法发生异常,那A和B方法的SQL都会执行,并且事务不会回滚。
总结
我们发现同类和异类事务大致相同,比如A类A方法和B类B方法都有@Transactional
注解和A类A方法有@Transactional
注解,B类B方法没有注解都是一样的效果。
但是有一点不同的是:同类A方法没有@Transactional
注解,B方法有@Transactional
注解和A类A方法没有@Transactional
注解,B类B方法有@Transactional
注解,得到的效果是不一样的。
本期测试到此结束
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/160671.html