使用Spring注解方式管理事务
前面讲解了怎么使用@Transactional注解声明PersonServiceBean底下所有的业务方法需要事务管理,那么事务是如何来管理的呢?
我们知道当每个业务方法执行的时候,它都会打开事务,在业务方法执行结束之后,它就会结束事务。那么它什么时候决定这个事务提交,什么时候决定这个事务回滚呢?原先我们手工控制事务的时候,通常这个事务的提交或回滚是由我们来操纵的,那现在我们采用容器的声明式事务管理,那我们如何知道事务什么时候提交,什么时候回滚呢?答案是:Spring容器默认情况下对运行时异常,它会进行事务的回滚,如果它碰到的是用户异常,如检查时异常(checked exception),这时事务就不会回滚。
现在我们就来做一个实验。假设person表里面有如下记录:
如果现在我们要删除person表中id为5的记录,但是在PersonServiceBean类的delete()方法中,人为地抛出一个运行时异常,如下:
public void delete(Integer personid) {
jdbcTemplate.update("delete from person where id=?", new Object[]{personid},
new int[]{java.sql.Types.INTEGER});
throw new RuntimeException("运行期异常");
}
此时测试PersonServiceTest类中的delete()方法:
@Test
public void delete() {
personService.delete(5);
}
会发现Eclipse控制台打印出一个异常,立马查看person表,发现id为5的记录没有删除掉,这就说明了Spring容器默认情况下对运行时异常,它会进行事务的回滚。
如果在PersonServiceBean类的delete()方法中,人为地抛出一个检查时异常,如下:
public void delete(Integer personid) throws Exception {
jdbcTemplate.update("delete from person where id=?", new Object[]{personid},
new int[]{java.sql.Types.INTEGER});
throw new Exception("检查时异常");
}
为了不报错,我们还须将PersonService接口中的delete()方法签名修改为: