@Override
public void addClassify(Classify classify) {
classifyDao.insert(classify);
addClassify2(classify);
//int m = 1/0;
}
@Transactional
public void addClassify2(Classify classify) {
Classify m = new Classify();
m.setName("李四");
classifyDao.insert(m);
int n = 1/0;
}
如上,方法中带方法,第一个不带事务,第二个带事务,两条数据均插入数据库成功,尽管第二个方法报错了,但是依然执行成功
@Transactional
public void addClassify(Classify classify) {
classifyDao.insert(classify);
addClassify2(classify);
}
//无论加不加事务,两条数据均插入不成功
//@Transactional
public void addClassify2(Classify classify) {
Classify m = new Classify();
m.setName("李四");
classifyDao.insert(m);
int n = 1/0;
}
如上,第一个方法加事务,第二个方法无论加不加事务,两条数据都无法插入成功,数据被回滚
结论:
在一个Service内部,事务方法之间的嵌套调用,普通方法和事务方法之间的嵌套调用,都不会开启新的事务.
1. spring采用动态代理机制来实现事务控制,而动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!
2. Spring的事务管理是通过AOP实现的,其AOP的实现对于非final类是通过cglib这种方式,即生成当前类的一个子类作为代理类,然后在调用其下的方法时,会判断这个方法有没有@Transactional注解,如果有的话,则通过动态代理实现事务管理(拦截方法调用,执行事务等切面)。当b()中调用a()时,发现b()上并没有@Transactional注解,所以整个AOP代理过程(事务管理)不会发生。
(注意try catch会使事务失效,事务有效的前提是异常是抛出去的)
spring事务中:无论第一个方法中是否存在操作数据库的现象,都存在以下2点结论
1.第一个方法存在事务,只要包含的方法(包括包含方法中包含的方法(嵌套方法))中出现异常,所有数据就会回滚
2.第一个方法不存在事务,无论包含的方法中是否存在事务,都会使包含的方法的事务失效,即y异常之前的数据都会成功