Spring Transaction

目錄說明

1 概述


是指作為單個邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行园担,要么完全地不執(zhí)行旨椒。事務可以分為編程式事務聲明式事務

編程式事務控制又叫細粒度事務的控制魔吐,可以針對指定的方法以及方法中具體的某一行代碼添加事務控制扎筒。需要自己每次手動的去添加莱找,開發(fā)比較繁瑣,每次都要開啟嗜桌、提交奥溺、回滾。

  • jdbc 代碼:conn.setAutoCommite(false) //設置手動控制事務
  • hibernate 代碼:session.beginTransaction() //開啟一個事務

聲明式事務又叫粗粒度事務的控制骨宠,只能給方法添加事務控制浮定。Spring 提供了對事務的管理,我們需要使用事務時只需要在配置文件中配置即可层亿,不使用時直接移除桦卒,這樣便大大的降低了事務控制的耦合。Spring 事務控制的實現(xiàn)是依賴與 Aop匿又。

2 事務控制的幾種方式


2.1 xml 實現(xiàn)

【1】步驟

  1. 引入 Spring-aop 相關的4個 jar
  2. 引入 aop 名稱空間
  3. 引入 tx 名稱空間
  4. 引入 Spring-jdbc 相關 jar(使用到spring jabcTemplate)

【2】實現(xiàn)
模擬: 在service中調用2次dao方灾, 希望其中一個dao執(zhí)行失敗,整個操作回滾

bean.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 1. 數(shù)據源對象: C3P0連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <property name="initialPoolSize" value="3"></property>
        <property name="maxPoolSize" value="10"></property>
        <property name="maxStatements" value="100"></property>
        <property name="acquireIncrement" value="2"></property>
    </bean>
    
    <!-- 2. 創(chuàng)建JdbcTemplate對象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 3.創(chuàng)建 Dao碌更、Service -->
    <bean id="userDao" class="com.acey.tx.a_xml_tx.UserDao">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
    <bean id="userService" class="com.acey.tx.a_xml_tx.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>

    <!-- 4. 聲明式事務管理配置-->
    <!-- 4.1 配置事務管理器類-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 4.2 配置事務增強(如何管理)-->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!--(1)方法名中包含 find 的方法只讀-->
            <tx:method name="*find*" read-only="true"/>
            <!--(2)方法名中以 get 開頭的方法只讀-->
            <tx:method name="get*" read-only="true"/>
            <!--除了(1)和(2)其它的方法進行讀寫-->
            <tx:method name="*" read-only="false"/>
        </tx:attributes>
    </tx:advice>
    <!-- 4.3 aop 配置裕偿,攔截哪些方法應用事務管理-->
    <aop:config>
        <aop:pointcut id="pt" expression="execution(* com.acey.tx.a_xml_tx.*Service.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
    </aop:config>
</beans>

由于我們使用的是 jdbc 技術,所以我們在配置事務管理器類時使用的是
DataSourceTransactionManager痛单,如果我們使用的是 hibernate 技術嘿棘,我們需要使用
HibernateTransactionManager

2.2 注解實現(xiàn)

【1】步驟

  1. 引入 Aop 相關 jar
  2. bean.xml 中配置事務管理器類以及指定 注解方式實現(xiàn)聲明式事務
  3. 在需要添加事務控制的地方加上 @Transactional

@Transactional注解

  • 定義到方法上,當前方法使用 Spring 的聲明式事務
  • 定義在類上桦他,當前類的所有方法使用 Spring 的聲明式事務
  • 定義到父類上蔫巩,當執(zhí)行父類的方法時應用事務

【2】實現(xiàn)(核心代碼)

bean.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- 1. 數(shù)據源對象: C3P0連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <property name="initialPoolSize" value="3"></property>
        <property name="maxPoolSize" value="10"></property>
        <property name="maxStatements" value="100"></property>
        <property name="acquireIncrement" value="2"></property>
    </bean>
    
    <!-- 2. 創(chuàng)建JdbcTemplate對象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 3. 開啟注解掃描-->
    <context:component-scan base-package="com.acey.tx.b_anno_tx"/>
    <!-- 4.創(chuàng)建事務管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 5.開啟事務注解-->
    <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
</beans>

UserDao.class

@Repository
public class UserDao {
    @Resource
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

//    @Transactional(
//            readOnly = false,   //讀寫事務
//            timeout = -1,       //事務的超時時間(-1(默認值)表示不限制)
//            noRollbackFor = ArithmeticException.class,    //遇到數(shù)學類異常不回滾
//            propagation = Propagation.REQUIRED      //事務的傳播行為
//    )
    @Transactional
    public void save(String name) {
        String sql = "insert into t_user (name) values(?)";
        jdbcTemplate.update(sql, name);
        int i = 1 / 0;//異常
        jdbcTemplate.update(sql, name);
    }
}

3 事務屬性


@Transactional(
            readOnly = false,   //讀寫事務
            timeout = -1,       //事務的超時時間(-1(默認值)表示不限制)
            noRollbackFor = ArithmeticException.class,    //遇到數(shù)學類異常不回滾
            propagation = Propagation.REQUIRED      //事務的傳播行為
    )

其中事務傳播行分為:

  • Propagation.REQUIRED
    指定當前的方法必須在事務的環(huán)境下執(zhí)行;
    如果當前運行的方法快压,已經存在事務圆仔, 就會加入當前的事務;
  • Propagation.REQUIRED_NEW
    指定當前的方法必須在事務的環(huán)境下執(zhí)行蔫劣;
    如果當前運行的方法坪郭,已經存在事務: 事務會掛起; 會始終開啟一個新的事務脉幢,執(zhí)行完后歪沃;
    剛才掛起的事務才繼續(xù)運行。

所有實例代碼地址 https://github.com/Aceysx/SpringDemo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末嫌松,一起剝皮案震驚了整個濱河市沪曙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萎羔,老刑警劉巖液走,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡缘眶,警方通過查閱死者的電腦和手機嘱根,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巷懈,“玉大人该抒,你說我怎么就攤上這事《パ啵” “怎么了凑保?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涌攻。 經常有香客問我愉适,道長,這世上最難降的妖魔是什么癣漆? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮剂买,結果婚禮上惠爽,老公的妹妹穿的比我還像新娘。我一直安慰自己瞬哼,他們只是感情好婚肆,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坐慰,像睡著了一般较性。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上结胀,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天赞咙,我揣著相機與錄音,去河邊找鬼糟港。 笑死攀操,一個胖子當著我的面吹牛,可吹牛的內容都是我干的秸抚。 我是一名探鬼主播速和,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼剥汤!你這毒婦竟也來了颠放?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤吭敢,失蹤者是張志新(化名)和其女友劉穎碰凶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡痒留,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年谴麦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伸头。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡匾效,死狀恐怖,靈堂內的尸體忽然破棺而出恤磷,到底是詐尸還是另有隱情面哼,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布扫步,位于F島的核電站魔策,受9級特大地震影響,放射性物質發(fā)生泄漏河胎。R本人自食惡果不足惜闯袒,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望游岳。 院中可真熱鬧政敢,春花似錦、人聲如沸胚迫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽访锻。三九已至褪尝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間期犬,已是汗流浹背河哑。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留龟虎,地道東北人灾馒。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像遣总,于是被迫代替她去往敵國和親睬罗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理旭斥,服務發(fā)現(xiàn)容达,斷路器,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評論 6 342
  • 什么是Spring Spring是一個開源的Java EE開發(fā)框架垂券。Spring框架的核心功能可以應用在任何Jav...
    jemmm閱讀 16,461評論 1 133
  • 敬請所有冰火迷批評指正花盐。 “我們該回去了羡滑。”見四周的林地越來越暗算芯,蓋里德催促道柒昏。“反正野人已經死了熙揍≈暗唬” “死人嚇到...
    曾培然閱讀 50,357評論 66 63
  • 作者:盼望長大 聽了和看了項目同伴們的分享,她們內心深深的感悟和流暢的表達届囚,讓我明白有梆,我是有差距的,因為書讀得不到...
    wendy聶的成長圈閱讀 623評論 0 0