说明,基于上篇的代码之上。
1.这里我们为了方便,使用声明书事务(注解方式),先简单看看Spring事务的几个属性:
属性名 | 说明 |
---|---|
name | 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。 |
propagation | 事务的传播行为,默认值为 REQUIRED。() |
isolation | 事务的隔离度,默认值采用 DEFAULT。 |
timeout | 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。 |
read-only | 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。 |
rollback-for | 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。 |
no-rollback- for | 抛出 no-rollback-for 指定的异常类型,不回滚事务。 |
几个传播行为:
PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。
2.代码里面添加事务注解即可:注解@Transactional(rollbackFor = Exception.class)
1.加在类和接口上:
表示实现该接口的方法和该类的所以public方法都开启事务,且抛出Exception以及其子类的时候进行回滚(运行时异常)。
2.加在指定的类的方法上面:
表示只对该方法开启注解,优点:开启事务开销大,指定具体的减少开销,提高性能。
3.注:
如果方法里面对方法进行了捕获,且不抛出,则不触发事务回滚。
事务一般加在Service层(业务层)
3.测试
先删除数据库表的数据进行测试
代码不添加事务:
public User save(User user) {
User u = new User();
u = userDao.save(user);
int num = 1/0;
return u;
}
以上代码虽然抛出异常,但执行结果还是保存成功:
方法添加事务:
@Transactional(rollbackFor = Exception.class)
public User save(User user) {
User u = new User();
u = userDao.save(user);
int num = 1/0;
return u;
}
执行结果没有新增数据,事务生效并遇到异常回滚:
对异常的代码捕获:
@Transactional(rollbackFor = Exception.class)
public User save(User user) {
User u = new User();
u = userDao.save(user);
try {
int num = 1/0;
} catch (Exception e) {
e.printStackTrace();
}
return u;
}
执行结果,保存成功,同时也可以看出id隔了一个25,也就是上面的回滚数据:
如果捕获部分重新抛出异常,则也会数据回滚,因为事务是aop编程,只要检测到该方法抛出异常,并不在内部进行处理,就能出发事务并回滚。其他加在类以及接口上面,跟加在方法上面一致,可以自行测试验证,我已验证ok。