Spring入门学习(事务的其它属性)
事务的隔离级别
- 使用
isolation
指定事务的隔离级别,最常用的取值为READ_COMMITTED
事务的回滚
- 默认情况下Spring 的声明式事务对所有的运行时异常进行回滚,也可以通过对应的属性进行设置,通常情况下取默认值即可。
- 此时测试:
由于当前余额只有30,所以发生异常后事务会回滚,余额和库存都不会发生变化。@Test public void testBookShopService() { bookShopService.purchase("AA", "1001"); }
- 当我们使用
noRollbackFor
指定那些异常不会滚后:
再次执行后,虽然发生了余额不足的异常,但是1001的库存还是减少了一个,即@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, noRollbackFor={UserAccountException.class})
UserAccountException
异常不会回滚,通常情况下取默认值即可。
事务的只读属性和过期时间
- 使用
readOnly
指定事务是否为只读,表示这个事务只读取但不进行更新,这样可以帮助数据库引擎优化事务。若真的只是一个读取数据库值的方法,应设置readOnly=true
。 - 使用
timeout
指定强制回滚之前事务可以占用的时间。 - 修改AA余额为3000,超时时间
timeout =3
,purchase
中睡眠2s,此时可以购买成功。
测试方法:@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, readOnly=false, timeout=3) @Override public void purchase(String username, String isbn) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 1.获取书的单价 int price = bookShopDao.findBookPriceByIsbn(isbn); // 2.更新书的库存 bookShopDao.updateBookStock(isbn); // 3.更新用户余额 bookShopDao.updateUserAccount(username, price); }
执行结果:执行成功,1001库存减1本,余额2900。@Test public void testBookShopService() { bookShopService.purchase("AA", "1001"); }
- 此时将睡眠时间改为5s
Thread.sleep(5000);
,会由于超时而回滚,库存和余额都不会发生变化。
测试结果如下: