}
因?yàn)閟aveTwo的傳播特性設(shè)置為requires_new,saveTwo方法單獨(dú)起一個(gè)事務(wù),所以當(dāng)調(diào)用saveOne拋出異常之后,不會(huì)影響saveTwo事務(wù)提交,事實(shí)上,在saveTwo返回之前已經(jīng)將事務(wù)提交,所以p1、p2對(duì)象能保存入庫(kù);
如果將saveTwo方法的傳播特性設(shè)置為required,這時(shí)候三個(gè)方法公用一個(gè)事務(wù),當(dāng)saveOne拋出異常后,整個(gè)事務(wù)回滾,數(shù)據(jù)不能入庫(kù);
場(chǎng)景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);
}
因?yàn)楫惓1籧atch了,所以事務(wù)不回滾,p1正常入庫(kù);
場(chǎng)景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);
}
開(kāi)始以為有了try catch,p1能保存進(jìn)去,但經(jīng)過(guò)測(cè)試,發(fā)現(xiàn)會(huì)報(bào)錯(cuò)。因?yàn)閟aveTwo時(shí)拋出異常,首先被spring框架個(gè)catch住,將事務(wù)標(biāo)記為rollbackonly,然再往出拋異常,最后被savePerson方法catch住,所以事務(wù)能夠提交,但當(dāng)提交的時(shí)候,
發(fā)現(xiàn)標(biāo)志位已經(jīng)被設(shè)置了,不應(yīng)該去提交了,然后吭哧吭哧的回滾調(diào),再提示你已經(jīng)被設(shè)置成rollback-only了。
但如果saveTwo的傳播特性改為require_new,因?yàn)樗麊纹鹨粋€(gè)事務(wù),不會(huì)影響父事務(wù)的提交,所以p1能保存,p2失敗;
場(chǎng)景4:
事務(wù)在多個(gè)對(duì)象之間才有傳播特性
@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);
}
兩個(gè)方法在一個(gè)類里面,
saveTwo并沒(méi)有事務(wù),p1能提交;但如果把saveTwo放到另外一個(gè)類,則saveTwo就會(huì)有事務(wù),p1不能提交;
如果要同一個(gè)類里面的saveTwo執(zhí)行事務(wù),可在配置文件增加<aop:aspectj-autoproxy expose-proxy="true"/>,然后((Iservice)AopContext.currentProxy()).
saveTwo(),這樣執(zhí)行的就是代理的方法,就會(huì)有事務(wù)(Iservice必須是你定義的接口)