Spring事務(wù)事務(wù)是邏輯上的一組操作,要么都執(zhí)行,,要么都不執(zhí)行 事務(wù)的特性(ACID)
Spring管理事務(wù)的方式有幾種程序是否支持事務(wù)是取決于數(shù)據(jù)庫是否支持事務(wù)
Spring事務(wù)管理接口介紹Spring中事務(wù)管理相關(guān)的最重要的三個(gè)接口如下
PlatformTransactionManager:事務(wù)管理接口Spring并不直接管理事務(wù),,而是提供了多種事務(wù)管理器,。spring通過該事務(wù)管理接口為多個(gè)平臺(tái)提供了對(duì)應(yīng)的事務(wù)管理器,具體的實(shí)現(xiàn)就是各個(gè)平臺(tái)自己的事情了,。 該接口主要是將事務(wù)管理行為抽象出來,,然后不同的平臺(tái)去實(shí)現(xiàn)它,,可以保證提供給外部的行為不變,方便我們擴(kuò)展,。 TransactionDefinition:事務(wù)屬性該類定義了一些基本的事務(wù)屬性,。
TransactionStatus:事務(wù)狀態(tài)該接口用來記錄事務(wù)的狀態(tài),該接口定義了一組方法,,用來獲取或判斷事務(wù)的相應(yīng)狀態(tài)信息,。 public interface TransactionStatus{ boolean isNewTransaction(); // 是否是新的事務(wù) boolean hasSavepoint(); // 是否有恢復(fù)點(diǎn) void setRollbackOnly(); // 設(shè)置為只回滾 boolean isRollbackOnly(); // 是否為只回滾 boolean isCompleted; // 是否已完成 } 事務(wù)屬性詳解Spring事務(wù)傳播行為(枚舉類:Propagation)事務(wù)傳播行為是為了解決業(yè)務(wù)層之間互相調(diào)用的事務(wù)問題。 當(dāng)事務(wù)方法被另一個(gè)事務(wù)方法調(diào)用時(shí),,必須制定事務(wù)應(yīng)該如何傳播,。例如:方法可能繼續(xù)在現(xiàn)有的事務(wù)中運(yùn)行,也可能開啟一個(gè)新事務(wù),,并在自己的事務(wù)中運(yùn)行,。
Spring事務(wù)中的隔離級(jí)別(枚舉類:Isolation)TransactionDefinition接口中定義了五個(gè)表示隔離級(jí)別的常量,。
事務(wù)超時(shí)屬性所謂事務(wù)超時(shí),就是指一個(gè)事務(wù)所允許執(zhí)行的最長(zhǎng)時(shí)間,,如果超過該時(shí)間限制但事務(wù)還沒有完成,,則自動(dòng)回滾事務(wù)。在TransactionDefinition中以int的值來表示超時(shí)時(shí)間,,其單位是秒,,默認(rèn)值是-1 事務(wù)只讀屬性對(duì)于只有讀取數(shù)據(jù)查詢的事務(wù),可以指定事務(wù)類型為readonly,,即只讀屬性,。只讀事務(wù)不涉及數(shù)據(jù)的修改,數(shù)據(jù)庫會(huì)提供一些優(yōu)化手段,,適合用在有多條數(shù)據(jù)庫查詢操作的方法中,。
如果不加Transaction,,每條sql會(huì)開啟一個(gè)單獨(dú)的事務(wù),中間被其他事務(wù)改了數(shù)據(jù),,都會(huì)實(shí)時(shí)讀取到最新值,。 如果你一次執(zhí)行多條查詢語句,,例如統(tǒng)計(jì)查詢,報(bào)表查詢,,在這種場(chǎng)景下,,多條查詢 SQL 必須保證整體的讀一致性,否則,,在前條 SQL 查詢之后,,后條 SQL 查詢之前,數(shù)據(jù)被其他用戶改變,,則該次整體的統(tǒng)計(jì)查詢將會(huì)出現(xiàn)讀數(shù)據(jù)不一致的狀態(tài),,此時(shí),應(yīng)該啟用事務(wù)支持 事務(wù)回滾規(guī)則這些規(guī)則定義了那些異常會(huì)導(dǎo)致事務(wù)回滾而那些不會(huì),。默認(rèn)情況下,,事務(wù)只有遇到了運(yùn)行時(shí)異常(RuntimeException的子類)時(shí)才會(huì)回滾,Error也會(huì)導(dǎo)致事務(wù)回滾,,但是在遇到檢查型(Checked)異常時(shí)不會(huì)回滾,。 如果要定義你回滾的異常類型可以這樣 @Transactional(rollbackFor = MyException.class) @Transaction注解作用范圍
常用配置參數(shù)@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Transactional { @AliasFor("transactionManager") String value() default ""; @AliasFor("value") String transactionManager() default ""; Propagation propagation() default Propagation.REQUIRED; Isolation isolation() default Isolation.DEFAULT; int timeout() default TransactionDefinition.TIMEOUT_DEFAULT; boolean readOnly() default false; Class<? extends Throwable>[] rollbackFor() default {}; String[] rollbackForClassName() default {}; Class<? extends Throwable>[] noRollbackFor() default {}; String[] noRollbackForClassName() default {}; } @Transactional的常用配置參數(shù)總結(jié)
@Transaction事務(wù)注解原理@Transaction的工作機(jī)制是基于AOP實(shí)現(xiàn)的,,AOP有事使用動(dòng)態(tài)代理實(shí)現(xiàn)的。如果目標(biāo)對(duì)象實(shí)現(xiàn)了接口,,默認(rèn)情況下采用JDK的動(dòng)態(tài)代理,,如果對(duì)象沒有實(shí)現(xiàn)接口,會(huì)使用Cglib來做動(dòng)態(tài)代理
如果一個(gè)類或者一個(gè)類中的public方法上被標(biāo)注@Transaction注解的話,,Spring容器會(huì)在啟動(dòng)的時(shí)候?yàn)槠鋭?chuàng)建一個(gè)代理類,,在調(diào)用被@Transaction注解的public方法的時(shí)候,實(shí)際調(diào)用的是TransactionInterceptor類中的invoke方法,。這個(gè)方法的作用就是在目標(biāo)方法之前開啟事務(wù),,方法執(zhí)行過程中如果遇到異常的時(shí)候回滾事務(wù),方法調(diào)用完成后提交事務(wù),。 注解失效情況應(yīng)用在非public修飾的方法上Spring AOP自調(diào)用問題若同一類中的其他沒有@Transaction注解的方法內(nèi)部調(diào)用有@Transaction注解的方法,,有@Transaction注解的方法的事務(wù)會(huì)失效,。 這是由于Spring AOP代理的原因造成的,因?yàn)橹挥蠤Transaction注解的方法在類以外被調(diào)用的時(shí)候,,Spring事務(wù)管理才生效,。 解決方法就是避免同一類中自調(diào)用或者使用AspectJ取代Spring AOP代理。 propagation屬性設(shè)置錯(cuò)誤rollbackFor屬性設(shè)置錯(cuò)誤try/catch中沒有拋出異常導(dǎo)致失效數(shù)據(jù)庫不支持事務(wù)最后
——我是冢狐,,和你一樣熱愛編程,。 |
|