2.1 Spring事務(wù)原理
Spring支持編程式事務(wù)和聲明式事務(wù)鳍徽。編程式事務(wù)就是用個(gè)事務(wù)類TransactionTemplate來管理事務(wù),現(xiàn)在基本沒人用堕花。聲明式事務(wù)分成在xml里配置個(gè)AOP來聲明個(gè)切面加事務(wù)哮内,目前也比較少人用,大部分情況下都是用@Transactional注解泽铛。
@Transactional注解尚辑,根據(jù)阿里編碼規(guī)范,一般建議加在方法級(jí)別盔腔,就是要事務(wù)的方法就加事務(wù)杠茬,不要事務(wù)的方法就別加事務(wù),否則很多一個(gè)數(shù)據(jù)庫(kù)操作的方法弛随。另外這個(gè)注解一般要加rollbackFor瓢喉,指定哪些異常類型才要回滾事務(wù)。還有就是有個(gè)isolation屬性舀透,可以自己手動(dòng)調(diào)整事務(wù)的隔離級(jí)別栓票。
Spring事務(wù)的基本原理:
Spring事務(wù)框架源碼初探:
2.2 Spring事務(wù)傳播行為
public class ServiceA {
@Autowired
private ServiceB b;
@Transactional
public void method() {
// 數(shù)據(jù)庫(kù)操作
b.methodB();
}
}
public class ServiceB {
@Transactional
public void method() throws Exception {
//數(shù)據(jù)庫(kù)操作
}
}
PROPAGATION_REQUIRED:默認(rèn),如果ServiceA.method調(diào)用了ServiceB.method愕够,如果ServiceA.method開啟了事務(wù)走贪,然后ServiceB.method也聲明了事務(wù),那么ServiceB.method不會(huì)開啟獨(dú)立事務(wù)链烈,而是將自己的操作放在ServiceA.method的事務(wù)中來執(zhí)行厉斟,ServiceA和ServiceB任何一個(gè)報(bào)錯(cuò)都會(huì)導(dǎo)致整個(gè)事務(wù)回滾。
PROPAGATION_SUPPORTS:如果ServiceA.method開了事務(wù)强衡,那么ServiceB就將自己加入ServiceA中來運(yùn)行擦秽,如果ServiceA.method沒有開事務(wù),那么ServiceB自己也不開事務(wù)漩勤。
PROPAGATION_MANDATORY:必須被一個(gè)開啟了事務(wù)的方法來調(diào)用自己感挥,否則報(bào)錯(cuò)。
PROPAGATION_REQUIRES_NEW:ServiceB.method強(qiáng)制性自己開啟一個(gè)新的事務(wù)越败,然后ServiceA.method的事務(wù)會(huì)卡住触幼,等ServiceB事務(wù)完了自己再繼續(xù)。這就是影響的回滾了究飞,如果ServiceA報(bào)錯(cuò)了置谦,ServiceB是不會(huì)受到影響的堂鲤,ServiceB報(bào)錯(cuò)了,ServiceA也可以選擇性的回滾或者是提交媒峡。
PROPAGATION_NOT_SUPPORTED:就是ServiceB.method不支持事務(wù)瘟栖,ServiceA的事務(wù)執(zhí)行到ServiceB那兒,就掛起來了谅阿,ServiceB用非事務(wù)方式運(yùn)行結(jié)束半哟,ServiceA事務(wù)再繼續(xù)運(yùn)行。這個(gè)好處就是ServiceB代碼報(bào)錯(cuò)不會(huì)讓ServiceA回滾签餐。
PROPAGATION_NEVER:不能被一個(gè)事務(wù)來調(diào)用寓涨,ServiceA.method開事務(wù)了,但是調(diào)用了ServiceB會(huì)報(bào)錯(cuò)
PROPAGATION_NESTED:開啟嵌套事務(wù)氯檐,ServiceB開啟一個(gè)子事務(wù)戒良,如果回滾的話,那么ServiceB就回滾到開啟子事務(wù)的這個(gè)save point男摧。