小白菜冠王,剛學(xué)spring aop的事務(wù)傳播特性赶撰,比較重要的三個(gè)REQUIRED,REQUIRES_NEW柱彻,NESTED自己的理解豪娜,發(fā)出來(lái)自己可以時(shí)常看看哟楷,也歡迎指正瘤载!
貼一些核心代碼,兩個(gè)實(shí)現(xiàn)類卖擅,
不用關(guān)心內(nèi)部實(shí)現(xiàn)鸣奔,只要將關(guān)注點(diǎn)放在Propagation上
@Repository
public class BookService {
@Autowired
BookDao bookDao;
@Transactional(propagation = Propagation.REQUIRED)
public void buyBook(String username,int id){
int price = bookDao.getPrice(id);
String bookname = bookDao.getBookName(id);
bookDao.updateBalance(username,price);
bookDao.updateStock(id);
// int i=1/0;
System.out.println(username+" 花了"+price+"元,買了一本"+bookname);
}
@Transactional(propagation = Propagation.REQUIRED)
public void updatePrice(int id){
String bookname = bookDao.getBookName(id);
bookDao.updatePrice(id);
int price = bookDao.getPrice(id);
// int i= 1/0;
System.out.println(bookname+"現(xiàn)價(jià):"+price);
}
}
@Service
public class MultService {
@Autowired
BookService bookService;
@Transactional
public void mult(){
bookService.buyBook("zhangsan",1);
bookService.updatePrice(1);
int i=1/0;
}
}
可以看出MultService里面是調(diào)用了BookService 的惩阶,我們將BookService 視為內(nèi)部挎狸,MultService視為外部
@Transactional(propagation = Propagation.REQUIRED)
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Transactional(propagation = Propagation.NESTED)
主要說明上面三種情況
1、事務(wù)傳播級(jí)別是REQUIRED断楷,當(dāng)buyBook()被調(diào)用時(shí)(假定被另一類中commit()調(diào)用)锨匆,如果buyBook()中的代碼拋出異常,即便被捕獲冬筒,commit()中的其他代碼都會(huì)roll back恐锣,相當(dāng)于只要任何一個(gè)有異常,無(wú)論是自己還是別人舞痰,最終都會(huì)回滾(因?yàn)樽钔鈱舆€嵌套了一層事務(wù))土榴。
2、是REQUIRES_NEW响牛,如果buyBook()中的代碼拋出異常玷禽,并且被捕獲,commit()中的其他代碼不會(huì)roll back呀打;如果commit()中的其他代碼拋出異常论衍,而且沒有捕獲,不會(huì)導(dǎo)致buyBook()回滾聚磺,可以想象成加了REQUIRES_NEW就等于自己是一個(gè)相對(duì)獨(dú)立的事務(wù)坯台,我自己有異常,我就會(huì)回滾瘫寝,我沒異常蜒蕾,別人有異常也不會(huì)影響我提交稠炬。
3、是NESTED咪啡,如果buyBook()中的代碼拋出異常首启,并且被捕獲,commit()中的其他代碼不會(huì)roll back撤摸;如果commit()中的其他代碼拋出異常毅桃,而且沒有捕獲,會(huì)導(dǎo)致buyBook()回滾准夷,簡(jiǎn)單理解如果內(nèi)層方法都正常钥飞,但是外層出了異常,(看外層方法加了個(gè)1/0會(huì)導(dǎo)致異常衫嵌,分母不能為0读宙。)最后還是會(huì)導(dǎo)致全部回滾。
public void mult(){
bookService.buyBook("zhangsan",1);
bookService.updatePrice(1);
int i=1/0;
}
最后再提一點(diǎn)REQUIRES_NEW和NESTED在外層都有異常時(shí)候的區(qū)別在于有REQUIRES_NEW注解的方法塊如果正常運(yùn)行楔绞,是可以直接commit的结闸,但是NESTED的不行,就這點(diǎn)區(qū)別酒朵。