Spring事務(wù)配置&&回滾失效的原因之一

2019-06-21_18-34.png

包名的配置問題

execution(* com.keeep.isrvbase.service.*.*(..)) 
//表示匹配com.keeep.isrvbase.service包下的所有方法
execution(* com.keeep.isrvbase.service..*.*(..)) 
 //表示匹配com.savage.server包及其子包下的所有方法

Spring 事務(wù)的隔離性

事務(wù)隔離級(jí)別:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
讀取未提交數(shù)據(jù)(會(huì)出現(xiàn)臟讀, 不可重復(fù)讀) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)
讀取已提交數(shù)據(jù)(會(huì)出現(xiàn)不可重復(fù)讀和幻讀)
@Transactional(isolation = Isolation.REPEATABLE_READ)
可重復(fù)讀(會(huì)出現(xiàn)幻讀)
@Transactional(isolation = Isolation.SERIALIZABLE)
串行化

MYSQL: 默認(rèn)為REPEATABLE_READ級(jí)別
SQLSERVER: 默認(rèn)為READ_COMMITTED

臟讀 : 一個(gè)事務(wù)讀取到另一事務(wù)未提交的更新數(shù)據(jù)  
不可重復(fù)讀 : 在同一事務(wù)中, 多次讀取同一數(shù)據(jù)返回的結(jié)果有所不同, 換句話說,后續(xù)讀取可以讀到另一事務(wù)已提交的更新數(shù)據(jù).   
相反, "可重復(fù)讀"在同一事務(wù)中多次讀取數(shù)據(jù)時(shí), 能夠保證所讀數(shù)據(jù)一樣, 也就是后續(xù)讀取不能讀到另一事務(wù)已提交的更新數(shù)據(jù)   
幻讀 : 一個(gè)事務(wù)讀到另一個(gè)事務(wù)已提交的insert數(shù)據(jù)

Spring事務(wù)的傳播行為

事物傳播行為介紹: 
@Transactional(propagation=Propagation.REQUIRED) 
如果有事務(wù), 那么加入事務(wù), 沒有的話新建一個(gè)(默認(rèn)情況下)
@Transactional(propagation=Propagation.NOT_SUPPORTED) 
容器不為這個(gè)方法開啟事務(wù)
@Transactional(propagation=Propagation.REQUIRES_NEW) 
不管是否存在事務(wù),都創(chuàng)建一個(gè)新的事務(wù),原來的掛起,新的執(zhí)行完畢,繼續(xù)執(zhí)行老的事務(wù)
@Transactional(propagation=Propagation.MANDATORY) 
必須在一個(gè)已有的事務(wù)中執(zhí)行,否則拋出異常
@Transactional(propagation=Propagation.NEVER) 
必須在一個(gè)沒有的事務(wù)中執(zhí)行,否則拋出異常(與Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS) 
如果其他bean調(diào)用這個(gè)方法,在其他bean中聲明事務(wù),那就用事務(wù).如果其他bean沒有聲明事務(wù),那就不用事務(wù).

事務(wù)配置

package com.keeep.isrvbase.pojo;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Table;

/**
 * 測(cè)試用例
 * @author congco
 */
@Setter
@Getter
@Table(name="tb_base_transaction_test")
public class TransactionTest {

    private Long id;

    private String name;

}

applicationContext-transaction.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 定義事務(wù)管理器 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 定義事務(wù)策略 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--所有以query開頭的方法都是只讀的 -->
            <tx:method name="query*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="select*" read-only="true"/>
            <!--其他方法使用默認(rèn)事務(wù)策略 -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--pointcut元素定義一個(gè)切入點(diǎn)组力,execution中的第一個(gè)星號(hào) 用以匹配方法的返回類型翔悠,
            這里星號(hào)表明匹配所有返回類型。 
      1)execution(* *(..))  
      //表示匹配所有方法  
      2)execution(public *  com.keeep.isrvbase.service.*(..))  
    //表示匹配 com.keeep.isrvbase.service中所有的公有方法  
    3)execution(* com.keeep.isrvbase.service..*.*(..)) 
    //表示匹配 com.keeep.isrvbase.service包及其子包下的所有方法
  
 -->
        <aop:pointcut id="myPointcut" expression="execution(* com.keeep.isrvbase.service..*.*(..))"/>
        <!--將定義好的事務(wù)處理策略應(yīng)用到上述的切入點(diǎn) -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
    </aop:config>

</beans>

mapper

package com.keeep.isrvbase.mapper;

import com.github.abel533.mapper.Mapper;
import com.keeep.isrvbase.pojo.TransactionTest;

/**
 * @author congco
 */
public interface TransactionTestMapper  extends Mapper<TransactionTest> {
}

service

package com.keeep.isrvbase.service;

import com.keeep.isrvbase.mapper.TransactionTestMapper;
import com.keeep.isrvbase.pojo.TransactionTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * created on 2020/4/10 上午11:58
 *
 * @author congco
 */
@Service
public class AnotherTransService {


    @Autowired
    private TransactionTestMapper mapper;
    public String testTrans() {
        try {
            TransactionTest test = new TransactionTest();
            test.setName("cong");
            this.mapper.insertSelective(test);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "over";
    }
}


//
package com.keeep.isrvbase.service.test;

import com.keeep.isrvbase.service.AnotherTransService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * @author congco
 * @date 19-5-27 下午7:25
 */
@Service
public class TransactionTestService {


    @Autowired
    public AnotherTransService anotherTransService;

    public String queryName() {
        return "Hello Congco";
    }


    public String saveName() {
        try {
            System.out.println("開始事務(wù)");
            this.anotherTransService.testTrans();
            int i =1/0;
            this.anotherTransService.testTrans();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        System.out.println("roll back");
        return "ok";
    }
}
 <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.9</version>
    <scope>test</scope>
   </dependency>
   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version> 3.2.4.RELEASE  </version>
    <scope>provided</scope>
 </dependency>

單元測(cè)試

package com.keeep.isrvbase.test;


import com.keeep.isrvbase.service.test.TransactionTestService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * created on 2020/4/10 上午11:21
 *
 * @author congco
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring/app*.xml")
public class TransactionTestServiceTest {

    @Autowired
    private TransactionTestService service;
    @Test
   public void queryName() {

        String name = this.service.queryName();
        System.out.println(name);
    }

    @Test
   public void saveName() {
        this.service.saveName();
    }
}

結(jié)果


GTWROg.png

數(shù)據(jù)庫(kù)表沒有插入新的數(shù)據(jù)

參考博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末混萝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子禀倔,更是在濱河造成了極大的恐慌熬芜,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曙强,死亡現(xiàn)場(chǎng)離奇詭異残拐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)碟嘴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門溪食,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人娜扇,你說我怎么就攤上這事错沃。” “怎么了袱衷?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵捎废,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我致燥,道長(zhǎng)阔挠,這世上最難降的妖魔是什么基显? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上啡直,老公的妹妹穿的比我還像新娘。我一直安慰自己帚呼,他們只是感情好质涛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱蝠,像睡著了一般续捂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宦搬,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天牙瓢,我揣著相機(jī)與錄音,去河邊找鬼间校。 笑死矾克,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的憔足。 我是一名探鬼主播胁附,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼酒繁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了控妻?” 一聲冷哼從身側(cè)響起州袒,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎饼暑,沒想到半個(gè)月后稳析,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弓叛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年彰居,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撰筷。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陈惰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出毕籽,到底是詐尸還是另有隱情抬闯,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布关筒,位于F島的核電站溶握,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蒸播。R本人自食惡果不足惜睡榆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望袍榆。 院中可真熱鬧胀屿,春花似錦、人聲如沸包雀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽才写。三九已至葡兑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赞草,已是汗流浹背讹堤。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留房资,地道東北人蜕劝。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓檀头,卻偏偏與公主長(zhǎng)得像轰异,于是被迫代替她去往敵國(guó)和親岖沛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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