您现在的位置是:首页 > 文章详情

Spring 的事务测试

日期:2018-07-17点击:297

自以为是

在我的想象当中,以为只要给这个方法注释成@Transactional, 就会处理事务,然而并非我想象的那样,今天测试了下事务,记录下

测试

1.首先建立一个JUnit 类来进行测试第一种方式

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath*:/applicationContext.xml" }) public class SpringTransTester { @Resource private UserMoneyMapper userMoney; @Transactional public void doInsert() { UserMoney ins = new UserMoney(); ins.setId("2"); ins.setBalance(100.00); userMoney.insert(ins); ins.setId("2"); // ID相同,会抛出异常 ins.setBalance(99.00); userMoney.insert(ins); } @Test public void testTrans() { List<UserMoney> list = userMoney.qryQuick("yangmf"); doInsert(); System.out.println("testTrans"); } }

数据库中插入了一条记录,第二条出现了错误,但是没有进行回滚
百度查了下资料:

通一个类里面如果A方法没有事务,调用带事务B方法,这样B方法的事务会被忽略。 

2. 改造下,把事务的方法单独放到Service中

// 注意该类放到Spring能扫描到的地方 @Service public class SpringTransService { @Resource private UserMoneyMapper userMoney; @Transactional public void doInnerInsert() { UserMoney ins = new UserMoney(); ins.setId("2"); ins.setBalance(100.00); userMoney.insert(ins); ins.setId("2"); // ID相同,会抛出异常 ins.setBalance(99.00); userMoney.insert(ins); } public void doInsert() { doInnerInsert(); } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath*:/applicationContext.xml" }) public class SpringTransTester { @Autowired private SpringTransService service; @Test public void testTrans() { service.doInsert(); System.out.println("testTrans"); } }

这样其实和第一种方法一样,由本类的方法来调用事务, 效果和第一个一样, 但是如果在doInsert上面也加上@Transactional,那么事务会起作用(doInnerInsert,的注解可以去掉)

3. 再改造下

// 注意该类放到Spring能扫描到的地方 @Service public class SpringTransService { @Resource private UserMoneyMapper userMoney; @Transactional public void doInsert() { UserMoney ins = new UserMoney(); ins.setId("2"); ins.setBalance(100.00); userMoney.insert(ins); ins.setId("2"); // ID相同,会抛出异常 ins.setBalance(99.00); userMoney.insert(ins); } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath*:/applicationContext.xml" }) public class SpringTransTester { @Autowired private SpringTransService service; @Test public void testTrans() { service.doInsert(); System.out.println("testTrans"); } }

这样可以,插入第二条是出现了一次,记录没有插入进去

4. 再测试下抛出Exception异常

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath*:/applicationContext.xml" }) public class SpringTransTester { @Autowired private SpringTransService service; @Test // 加上抛出异常 public void testTrans() throws Exception { service.doInsert(); System.out.println("testTrans"); } } 
@Service public class SpringTransService { @Resource private UserMoneyMapper userMoney; // 手动抛出异常 @Transactional public void doInsert() throws Exception { UserMoney ins = new UserMoney(); ins.setId("2"); ins.setBalance(100.00); userMoney.insert(ins); ins.setId("3"); // ID不同相同,会抛出异常 ins.setBalance(99.00); userMoney.insert(ins); throw new Exception("测试事务"); } }

异常抛出了,事务没有起作用,数据都存进去了会, 如果把Exception改成RuntimeException,事务会进行回滚,看来异常不能简单的写个Exception。可以继承RuntimeException

原文链接:https://yq.aliyun.com/articles/614013
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章