spring boot實戰(zhàn)之事務(wù)

事務(wù)在項目里也是不可或缺的一部分朵栖,建議形成一個統(tǒng)一的事務(wù)管理規(guī)范责循,不要出現(xiàn)讓程序員根據(jù)業(yè)務(wù)自行添加撮珠,團隊成員能力有高有低,很容易就出現(xiàn)需要事務(wù)時沒添加事務(wù)塌忽,這種問題又很難測試出來拍埠,運行時卻會不定時出現(xiàn)數(shù)據(jù)的不一致土居。
想實現(xiàn)類似原spring項目里通過aop方式配置事務(wù)的效果,各種嘗試棉圈,目前還未找到十分可行的方式迄损。測試可用的事務(wù)配置方式有兩種:在service上添加@Transactional注解 和 引入xml配置文件(不推薦)账磺,建議使用@Transactional注解來進行事務(wù)配置垮抗。

1冒版、@Transactional實現(xiàn)事務(wù)

spring boot項目內(nèi)使用事務(wù)最簡單直接的方式就是在每個service類上添加@Transactional注解,即可自動開啟對事務(wù)的支持捆等,不需要進行額外操作。

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED)

該注解也可添加在方法上谒养,對事物進行更精細化的管理明郭,注意引用spring包下的薯定,不要引用javax包下的话侄。

2、引入xml配置實現(xiàn)事務(wù)

1径簿、 創(chuàng)建com.onecoderspace.transaction.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"
    default-lazy-init="false" default-autowire="no">

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />
    <!-- 對于service使用annotation聲明事物 -->
    <tx:annotation-driven mode="proxy" proxy-target-class="true" transaction-manager="transactionManager" order="100" />
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="insert*" isolation="REPEATABLE_READ" />
            <tx:method name="save*" isolation="REPEATABLE_READ" />
            <tx:method name="update*" isolation="REPEATABLE_READ" />
            <tx:method name="del*" isolation="REPEATABLE_READ" />
            <tx:method name="do*" isolation="REPEATABLE_READ" />
            <tx:method name="*" isolation="REPEATABLE_READ" read-only="true" />
        </tx:attributes>
    </tx:advice>
    
    <aop:config proxy-target-class="true">
        <aop:advisor pointcut="execution(* com.onecoderspace..*.service..*.*(..))" advice-ref="txAdvice" order="200" />
    </aop:config>
</beans>

2锄贷、引入xml配置文件

@Configuration
@ImportResource("classpath:com.onecoderspace.transaction.xml")
public class AopTransactionConfig {
    
}

3谊却、小結(jié)

  1. service層需要統(tǒng)一添加事務(wù)哑芹,避免部分人員忘記事務(wù)處理聪姿,在運行過程中導(dǎo)致數(shù)據(jù)不一致末购;
  2. 在每個service上添加注解實現(xiàn)事務(wù):定好項目整體事務(wù)隔離級別和傳播屬性即可在項目級別形成規(guī)范盟榴,勝在簡單,可執(zhí)行性更高羽德,目前本公司使用該方式;
  3. 在service方法上添加注解實現(xiàn)事務(wù):事務(wù)管理更靈活银觅,更有針對性究驴,缺點是難以形成統(tǒng)一規(guī)范匀伏,依賴編程人員的經(jīng)驗和能力,如果團隊內(nèi)存在經(jīng)驗不很充足的成員不推薦使用該方式熙侍;
  4. 通過引入xml配置實現(xiàn)事務(wù):配置簡單蛉抓,在xml內(nèi)一處配置即可實現(xiàn)事務(wù)管理巷送,耦合性更低矛辕;缺點就是使用了xml配置聊品,因此不太推薦使用該方式翻屈;
  5. 隔離級別(isolation)通常選擇REPEATABLE_READ;傳播屬性通常使用默認值(REQUIRED)即可惊窖。

4爬坑、擴展閱讀

隔離級別(isolation)

隔離級別是指若干個并發(fā)的事務(wù)之間的隔離程度盾计,與我們開發(fā)時候主要相關(guān)的場景包括:臟讀取族铆、重復(fù)讀哥攘、幻讀材鹦。

我們可以看 org.springframework.transaction.annotation.Isolation 枚舉類中定義了五個表示隔離級別的值:

public enum Isolation {  
    DEFAULT(-1),
    READ_UNCOMMITTED(1),
    READ_COMMITTED(2),
    REPEATABLE_READ(4),
    SERIALIZABLE(8);
}
  • DEFAULT :這是默認值逝淹,表示使用底層數(shù)據(jù)庫的默認隔離級別。對大部分數(shù)據(jù)庫而言桶唐,通常這值就是: READ_COMMITTED栅葡,mysql5.6默認是REPEATABLE-READ,可以通過select @@tx_isolation查看尤泽。
  • READ_UNCOMMITTED :該隔離級別表示一個事務(wù)可以讀取另一個事務(wù)修改但還沒有提交的數(shù)據(jù)欣簇。該級別不能防止臟讀和不可重復(fù)讀,因此很少使用該隔離級別坯约。
  • READ_COMMITTED :該隔離級別表示一個事務(wù)只能讀取另一個事務(wù)已經(jīng)提交的數(shù)據(jù)熊咽。該級別可以防止臟讀,這也是大多數(shù)情況下的推薦值闹丐。
  • REPEATABLE_READ :該隔離級別表示一個事務(wù)在整個過程中可以多次重復(fù)執(zhí)行某個查詢横殴,并且每次返回的記錄都相同。即使在多次查詢之間有新增的數(shù)據(jù)滿足該查詢妇智,這些新增的記錄也會被忽略滥玷。該級別可以防止臟讀和不可重復(fù)讀。
  • SERIALIZABLE :所有的事務(wù)依次逐個執(zhí)行巍棱,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說蛋欣,該級別可以防止臟讀航徙、不可重復(fù)讀以及幻讀。但是這將嚴重影響程序的性能陷虎。通常情況下也不會用到該級別到踏。

傳播屬性(propagation)

所謂事務(wù)的傳播行為是指,如果在開始當前事務(wù)之前尚猿,一個事務(wù)上下文已經(jīng)存在窝稿,此時有若干選項可以指定一個事務(wù)性方法的執(zhí)行行為。

我們可以看 org.springframework.transaction.annotation.Propagation 枚舉類中定義了6個表示傳播行為的枚舉值:

public enum Propagation {  
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    NOT_SUPPORTED(4),
    NEVER(5),
    NESTED(6);
}
  • REQUIRED :如果當前存在事務(wù)凿掂,則加入該事務(wù)伴榔;如果當前沒有事務(wù)纹蝴,則創(chuàng)建一個新的事務(wù)。
  • SUPPORTS :如果當前存在事務(wù)踪少,則加入該事務(wù)塘安;如果當前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運行援奢。
  • MANDATORY :如果當前存在事務(wù)兼犯,則加入該事務(wù);如果當前沒有事務(wù)集漾,則拋出異常切黔。
  • REQUIRES_NEW :創(chuàng)建一個新的事務(wù),如果當前存在事務(wù)具篇,則把當前事務(wù)掛起纬霞。
  • NOT_SUPPORTED :以非事務(wù)方式運行,如果當前存在事務(wù)栽连,則把當前事務(wù)掛起险领。
  • NEVER :以非事務(wù)方式運行,如果當前存在事務(wù)秒紧,則拋出異常绢陌。
  • NESTED :如果當前存在事務(wù),則創(chuàng)建一個事務(wù)作為當前事務(wù)的嵌套事務(wù)來運行熔恢;如果當前沒有事務(wù)脐湾,則該取值等價于 REQUIRED 。

如有更好實現(xiàn)方式叙淌,敬請指出秤掌。

《spring boot項目實戰(zhàn)》之事務(wù)使用,本人搭建好的spring boot web后端開發(fā)框架已上傳至GitHub鹰霍,歡迎吐槽闻鉴!
https://github.com/q7322068/rest-base,已用于多個正式項目,當前可能因為版本問題不是很完善茂洒,后續(xù)持續(xù)優(yōu)化孟岛,希望你能有所收獲!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末督勺,一起剝皮案震驚了整個濱河市渠羞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌智哀,老刑警劉巖次询,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瓷叫,居然都是意外死亡屯吊,警方通過查閱死者的電腦和手機送巡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雌芽,“玉大人授艰,你說我怎么就攤上這事∈缆洌” “怎么了淮腾?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長屉佳。 經(jīng)常有香客問我谷朝,道長,這世上最難降的妖魔是什么武花? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任圆凰,我火速辦了婚禮,結(jié)果婚禮上体箕,老公的妹妹穿的比我還像新娘专钉。我一直安慰自己,他們只是感情好累铅,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布跃须。 她就那樣靜靜地躺著,像睡著了一般娃兽。 火紅的嫁衣襯著肌膚如雪菇民。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天投储,我揣著相機與錄音第练,去河邊找鬼。 笑死玛荞,一個胖子當著我的面吹牛娇掏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勋眯,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼驹碍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凡恍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤怔球,失蹤者是張志新(化名)和其女友劉穎嚼酝,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竟坛,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡闽巩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媳搪。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡宣虾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隅很,到底是詐尸還是另有隱情撞牢,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布叔营,位于F島的核電站屋彪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绒尊。R本人自食惡果不足惜畜挥,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婴谱。 院中可真熱鬧蟹但,春花似錦、人聲如沸谭羔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽口糕。三九已至缅阳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間景描,已是汗流浹背十办。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留超棺,地道東北人向族。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像棠绘,于是被迫代替她去往敵國和親件相。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

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