Spring学习笔记之Spring事务及事务测试

spring事务:


  1.      * 说下事务的传播属性  
  2.      * REQUIRED (默认)    业务方法需要在事务中运行,如果方法运行的时候已经开启事务,就加入事务,否则创建新的事务 
  3.      * NOT_SUPPORTED    声明方法不需要开启事务.如果已经开启事务后调用该方法.则先挂起该事务,方法执行完毕后,事务恢复 
  4.      * REQUIRES_NEW     不管是否存在事务,都另行开启新的事务.如果先前已经开启事务,挂起原先事务.创建新的事务. 
  5.      *                  新的事务执行结束后,恢复原先事务 
  6.      * MANDATORY    只能在已经存在的事务中执行,不能自行创建事务,如果在没有开启事务的环境下调用,容器抛出例外 
  7.      * SUPPORTS     墙头草,有事务就在事务中执行.没事务就在没事务的环境下执行 
  8.      * NEVER    绝对不能在事务中执行.如果执行.抛出例外  
  9.      * NESTED   如果有事务存在,开启一个新事务嵌套在上层事务中.开启的新事务具有自己独立的回滚点.新事务的回滚不会对外部事务造成影响, 
  10.      *          但是外部事务的提交会直接提交嵌套事务 
  11.      *          如果没有事务存在,则按照REQUIRED属性执行,该属性只对DataSourceTransationManager事务管理器有效

上节讲的是spring整合jdbc,个人产生了些疑问,想测试一下.


问题1:  数据库事务在什么地方,觉得应该在业务层实现类中的每个方法的开始前和结束后,利用Spring的AOP特性,以每个方法切入点,加入的事务代码?


  1. ApplicationContext context = new ClassPathXmlApplicationContext("jdbcsource.xml");  
  2. UserInfoService userInfoService = (UserInfoService)context.getBean("userInfoService");  
  3.   
  4. @Test  
  5. public void test1(){  
  6.     UserInfo userInfo = new UserInfo();  
  7.     userInfo.setName("windskymr1");  
  8.     userInfoService.save(userInfo);  
  9.     throw new RuntimeException("发生了异常");  
  10. }  

数据库中加入了windskymr1用户,则事务不在test1方法中;

数据库手动操作删除windskymr1用户,再进行测试

  1. public void save(UserInfo userInfo) {  
  2.     jdbcTemp.update("insert into userinfo (name) values (?)"new Object[]{userInfo.getName()},   
  3.             new int[]{java.sql.Types.VARCHAR}  
  4.     );  
  5.     throw new RuntimeException("发生了异常");  
  6. }  

业务层修改了save方法,在其中抛出一个运行时异常,再进行测试,结果没有插入成功,因为事务回滚了,证明本人的猜测正确,业务层的每个方法就是一个事务.


问题2: (1)证明传播属性为REQUIRED的有效性?(2)如果同一时间有几个请求调用业务方法,那么所有请求都进入了同一个事务,如果这之中的有一个有异常,所有方法都被回滚,执行失败,这样会不会不太好呢?


  1. @Transactional(propagation=Propagation.REQUIRED)  
  2. public void save(UserInfo userInfo) {  
  3.     jdbcTemp.update("insert into userinfo (name) values (?)"new Object[]{userInfo.getName()},   
  4.             new int[]{java.sql.Types.VARCHAR}  
  5.     );  
  6.       
  7.     UserInfo ui = new UserInfo();  
  8.     ui.setId(1);  
  9.     ui.setName("updated_suc");  
  10.     update(ui);  
  11.     throw new RuntimeException("发生了异常");  
  12. }  
  13. @Transactional(propagation=Propagation.REQUIRED)  
  14. public void update(UserInfo userInfo) {  
  15.     jdbcTemp.update("update userinfo set name=? where id=?",   
  16.             new Object[]{userInfo.getName(), userInfo.getId()},  
  17.             new int[]{java.sql.Types.VARCHAR, java.sql.Types.INTEGER}   
  18.             );  
  19. }  

  1. ApplicationContext context = new ClassPathXmlApplicationContext("jdbcsource.xml");  
  2. UserInfoService userInfoService = (UserInfoService)context.getBean("userInfoService");  
  3.   
  4. @Test  
  5. public void test1(){  
  6.     UserInfo userInfo = new UserInfo();  
  7.     userInfo.setName("windskymr1");  
  8.     userInfoService.save(userInfo);  
  9. }  

测试后发现update方法并没有更新成功,证明外部事务与内部事务是同一个,update方法是加入了原事务,证明REQUIRED确定有效;

至于第(2)个小问,是本人理解有误,误认为是多个线程的调用而产生的多个事务,以为是这种情况下的事务会有关联,因为事务有隔离性,每个事务间不相互影响.


其他的属性可以照此测试...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值