Spring事務(wù)管理

事務(wù)回顧

事務(wù)指的是邏輯上的一組操作航徙,這組操作要么全部成功湿酸,要么全部失敗接剩。事務(wù)操作能夠保證數(shù)據(jù)操作的安全性枣氧。

以一個(gè)簡單的銀行轉(zhuǎn)賬案例說明,張三和李四賬戶都有兩千元截粗,現(xiàn)在張三要給李四轉(zhuǎn)賬1000元信姓,那么需要兩步操作,第一修改張三賬戶扣除1000元绸罗,第二修改李四賬戶增加1000元意推。這個(gè)轉(zhuǎn)賬操作不應(yīng)該出現(xiàn)張三轉(zhuǎn)賬時(shí)由于某種原因錢轉(zhuǎn)出去了但李四沒收到。所以對于這樣一組操作我們應(yīng)該用事務(wù)來進(jìn)行管理珊蟀。那么一旦這組操作加入到了事務(wù)管理之中左痢,它們就必須一起成功或者一起失敗。

事務(wù)的特性(ACID特性)
  1. 原子性(Atomicity)
    原子性是指事務(wù)是一個(gè)不可分割的工作單位系洛,事務(wù)中的操作要么都發(fā)生要么都不發(fā)生
  2. 一致性(Consistency)
    一致性指事務(wù)前后數(shù)據(jù)的完整性必須保持一致
  3. 隔離性(Isolation)
    事務(wù)的隔離性是指多個(gè)用戶并發(fā)訪問數(shù)據(jù)庫時(shí),一個(gè)用戶的事務(wù)不能被其他用戶的事務(wù)所干擾略步,多個(gè)并發(fā)事務(wù)之間數(shù)據(jù)要相互隔離
  4. 持久性(Durability)
    持久性是指一個(gè)事務(wù)一旦被提交描扯,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響

Spring事務(wù)接口

Spring事務(wù)管理高層抽象主要包括3個(gè)接口:PlatformTransactionManager平臺事務(wù)管理器趟薄,TransactionDefinition事務(wù)定義信息(隔離绽诚、傳播、超時(shí)杭煎、只讀)恩够,TransactionStatus事務(wù)具體運(yùn)行狀態(tài)。
Spring在進(jìn)行事務(wù)管理的時(shí)候首先會根據(jù)事務(wù)定義信息羡铲,由事務(wù)管理器真正進(jìn)行事務(wù)管理操作(事務(wù)提交蜂桶、回滾等),在進(jìn)行事務(wù)管理過程中事務(wù)會產(chǎn)生一些相應(yīng)的狀態(tài)也切,這些狀態(tài)就保存在TransactionStatus中扑媚。

PlatformTransactionManager接口

Spring為不同的持久化框架提供了不同PlatformTransactionManager接口實(shí)現(xiàn)腰湾,通常我們都是使用前兩種。

TransactionDefinition定義事務(wù)隔離級別

如果不考慮隔離性疆股,會引發(fā)安全問題如下:臟讀费坊、不可重復(fù)讀、幻讀旬痹,隔離級別就是用來解決這幾種讀的問題的附井。

正常情況下數(shù)據(jù)庫為我們提供了四種隔離級別,而default是spring提供的選擇項(xiàng)两残。

TransactionDefinition定義事務(wù)傳播行為

事務(wù)傳播行為主要解決業(yè)務(wù)層方法之間的相互調(diào)用而產(chǎn)生的事務(wù)應(yīng)該如何傳遞的問題永毅。比如在a方法中調(diào)用了b方法
對于第一種類型來說如果a里面有事務(wù),b方法就使用a的事務(wù)磕昼,如果a沒有事務(wù)卷雕,b方法就新建事務(wù),并把a(bǔ)內(nèi)容包裹進(jìn)來票从,意思是a和b這兩個(gè)操作是在同一個(gè)事務(wù)之間的漫雕。類型2/3表示a沒有事務(wù),b方法就不使用事務(wù)/拋出異常峰鄙。
后三種類型作為一類浸间,表示a和b這兩個(gè)操作沒有在同一個(gè)事務(wù)中。
最后一種類型是嵌套事務(wù)吟榴,當(dāng)a執(zhí)行完成以后可以設(shè)置一個(gè)保存點(diǎn)魁蒜,如果b發(fā)生異常之后可以回滾到保存點(diǎn)位置,或者最初始狀態(tài)吩翻。

TransactionDefinition接口方法

Timeout: 事務(wù)超時(shí)兜看,就是指一個(gè)事務(wù)所允許執(zhí)行的最長時(shí)間,如果超過該時(shí)間限制事務(wù)還沒有完成狭瞎,則自動回滾事務(wù)细移。
ReadOnly: 默認(rèn)為false,也就是讀寫事務(wù)熊锭,如果設(shè)置只讀事務(wù)則不允許對數(shù)據(jù)進(jìn)行增刪改弧轧,只讀事務(wù)用于特定情景下的優(yōu)化。

TransactionStatus接口

Spring事務(wù)管理

Spring支持兩種方式事務(wù)管理方式碗殷,編程式事務(wù)管理和聲明式事務(wù)管理精绎。
編程式事務(wù)管理通過TransactionTemplate手動管理事務(wù),在實(shí)際應(yīng)用中很少使用锌妻。聲明式事務(wù)管理是通過AOP實(shí)現(xiàn)的代乃,開發(fā)中推薦使用(代碼侵入性小)。

編程式事務(wù)管理

這種方式不推薦實(shí)際使用仿粹,僅提供實(shí)現(xiàn)思路供參考襟己。
1.配置事務(wù)管理器TransactionManager引谜,并在事務(wù)管理器中配置連接池dataSource屬性。

2.配置事務(wù)管理的模版TransactionTemplate擎浴,并在事務(wù)管理模版中配置事務(wù)管理器屬性员咽。

3.在業(yè)務(wù)類中注入模版類,并調(diào)用其方法進(jìn)行事務(wù)控制贮预。

聲明式事務(wù)管理

聲明式事務(wù)管理共有3種實(shí)現(xiàn)方式贝室,分別是基于TransactionProxyFactoryBean的方式、基于AspectJ的XML方式以及基于注解的方式仿吞。
由于第一種方式配置較為繁瑣(需要為每個(gè)進(jìn)行事務(wù)管理的類配置一個(gè)這樣的Bean進(jìn)行增強(qiáng))滑频,通常實(shí)際開發(fā)不采用,這里我們只介紹后兩種方式唤冈,也是實(shí)際開發(fā)常用的兩種方式峡迷。

基于AspectJ的XML方式

基于這種方式我們只需要進(jìn)行相關(guān)的配置即可,業(yè)務(wù)代碼不需要做任何處理你虹,注意在配置文件的頭部需要添加aop和tx的命名空間绘搞。

    <!-- 配置連接池,這里以druid為例傅物,連接池相關(guān)參數(shù)省略 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://xxx:3306/xxx"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root123"></property>
    </bean>
    
    <!-- 配置事務(wù)管理器 -->
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置事務(wù)的通知:(事務(wù)的增強(qiáng)) -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- propagation:事務(wù)傳播行為夯辖,isolation:事務(wù)隔離級別,read-only:只讀 -->
            <!-- rollback-for:發(fā)生哪些異扯危回滾蒿褂,no-rollback-for:發(fā)生哪些異常不回滾,timeout:超時(shí)時(shí)間 -->
            <tx:method name="delet*" propagation="REQUIRED" read-only="false" />
            <tx:method name="save*" propagation="REQUIRED" read-only="false" />
            <tx:method name="updat*" propagation="REQUIRED" read-only="false" />
            <tx:method name="*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <!-- AOP配置 -->
    <aop:config>
        <!-- 配置切入點(diǎn) -->
        <aop:pointcut expression="execution(* com.rxy.*.service.*Service.*(..))"" id="pointcut1" />
        <!-- 配置切面 -->
        <aop:advisor pointcut-ref="pointcut1" advice-ref="txAdvice" />
    </aop:config>
基于注解的方式
  1. 添加配置
    <!-- 配置事務(wù)管理器 -->
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 開啟注解事務(wù) -->
    <tx:annotation-driven transaction-manager="transactionManager" />
  1. 使用注解@Transactional
    @Transactional可以作用于接口卒暂、接口方法啄栓、類以及類方法上。當(dāng)作用于類上時(shí)也祠,該類的所有 public 方法將都具有該類型的事務(wù)屬性谴供,同時(shí),我們也可以在方法級別使用該標(biāo)注來覆蓋類級別的定義齿坷。
    我們更推薦將注解使用在類以及類方法上,而不是接口数焊。并且@Transactional注解應(yīng)該只被應(yīng)用到 public 方法上永淌。
//如果注解不定義任何屬性,會使用其默認(rèn)值佩耳,屬性的含義參考xml方式的配置說明
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public class AccountServiceImpl {
    //方法注解會覆蓋類注解上的相同屬性
    @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_UNCOMMITTED)
    public void transfer(final String out, final String in, final Double money){
        //業(yè)務(wù)邏輯遂蛀,調(diào)用dao方法
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市干厚,隨后出現(xiàn)的幾起案子李滴,更是在濱河造成了極大的恐慌螃宙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件所坯,死亡現(xiàn)場離奇詭異谆扎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芹助,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門堂湖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人状土,你說我怎么就攤上這事无蜂。” “怎么了蒙谓?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵斥季,是天一觀的道長。 經(jīng)常有香客問我累驮,道長酣倾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任慰照,我火速辦了婚禮灶挟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘毒租。我一直安慰自己稚铣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布墅垮。 她就那樣靜靜地躺著惕医,像睡著了一般。 火紅的嫁衣襯著肌膚如雪算色。 梳的紋絲不亂的頭發(fā)上抬伺,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音灾梦,去河邊找鬼峡钓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛若河,可吹牛的內(nèi)容都是我干的能岩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼萧福,長吁一口氣:“原來是場噩夢啊……” “哼拉鹃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤膏燕,失蹤者是張志新(化名)和其女友劉穎钥屈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坝辫,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篷就,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阀溶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腻脏。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖银锻,靈堂內(nèi)的尸體忽然破棺而出永品,到底是詐尸還是另有隱情,我是刑警寧澤击纬,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布鼎姐,位于F島的核電站,受9級特大地震影響更振,放射性物質(zhì)發(fā)生泄漏炕桨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一肯腕、第九天 我趴在偏房一處隱蔽的房頂上張望献宫。 院中可真熱鬧,春花似錦实撒、人聲如沸姊途。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捷兰。三九已至,卻和暖如春负敏,著一層夾襖步出監(jiān)牢的瞬間贡茅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工其做, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顶考,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓妖泄,卻偏偏與公主長得像驹沿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子浮庐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容