}
因为saveTwo的传播特性设置为requires_new,saveTwo方法单独起一个事务,所以当调用saveOne抛出异常之后,不会影响saveTwo事务提交,事实上,在saveTwo返回之前已经将事务提交,所以p1、p2对象能保存入库;
如果将saveTwo方法的传播特性设置为required,这时候三个方法公用一个事务,当saveOne抛出异常后,整个事务回滚,数据不能入库;
场景2:
aService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void savePerson() {
try{
Person p1 = new Person();
p1.setName("yangay");
Person p2 = new Person();
p2.setName("lisan");
messageBean.saveTwo(p1, null);
}catch(Exception ex){
ex.printStackTrace();
}
}
bService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void saveTwo(Person p1,Person p2){
this.dao.save(p1);
this.dao.save(p2);
}
因为异常被catch了,所以事务不回滚,p1正常入库;
场景3:
aService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void savePerson() {
try{
Person p1 = new Person();
p1.setName("yangay");
Person p2 = new Person();
p2.setName("lisan");
messageBean.saveOne(p1);
messageBean.saveTwo(p2, null);
}catch(Exception ex){
ex.printStackTrace();
}
}
bService代码:
@Transactional(propagation=Propagation.REQUIRED)
public void saveOne(Person p){
this.dao.save(p);
}
@Transactional(propagation=Propagation.REQUIRED)
public void saveTwo(Person p1,Person p2){
this.dao.save(p1);
this.dao.save(p2);
}
开始以为有了try catch,p1能保存进去,但经过测试,发现会报错。因为saveTwo时抛出异常,首先被spring框架个catch住,将事务标记为rollbackonly,然再往出抛异常,最后被savePerson方法catch住,所以事务能够提交,但当提交的时候,
发现标志位已经被设置了,不应该去提交了,然后吭哧吭哧的回滚调,再提示你已经被设置成rollback-only了。
但如果saveTwo的传播特性改为require_new,因为他单起一个事务,不会影响父事务的提交,所以p1能保存,p2失败;
场景4:
事务在多个对象之间才有传播特性
@Override
public void savePerson() {
Person p1 = new Person();
p1.setName("yangay");
Person p2 = new Person();
p2.setName("lisan");
saveTwo(p1,null);
}
@Transactional(propagation=Propagation.REQUIRED)
public void saveTwo(Person p1,Person p2){
messageBean.saveOne(p1);
messageBean.saveOne(p2);
}
两个方法在一个类里面,
saveTwo并没有事务,p1能提交;但如果把saveTwo放到另外一个类,则saveTwo就会有事务,p1不能提交;
如果要同一个类里面的saveTwo执行事务,可在配置文件增加<aop:aspectj-autoproxy expose-proxy="true"/>,然后((Iservice)AopContext.currentProxy()).
saveTwo(),这样执行的就是代理的方法,就会有事务(Iservice必须是你定义的接口)