Spring @Transactional 失效 和 傳播行為

首先,說大概說一下事務傳播行為践盼,隨后講事務失效,具體分析同一個類里方法調(diào)用造成事務失效的情況宾巍,再到事務傳播行為應該在不同類的事務方法傳播咕幻,最后講會如何傳播。

0. 事務傳播行為大概認識

  1. PROPAGATION_REQUIRED
    假如當前正要執(zhí)行的事務不在另外一個事務里顶霞,那么就起一個新的事務
    比如說肄程,ServiceB.methodB的事務級別定義為PROPAGATION_REQUIRED, 那么由于執(zhí)行ServiceA.methodA的時候,ServiceA.methodA已經(jīng)起了事務,這時調(diào)用ServiceB.methodB蓝厌,ServiceB.methodB看到自己已經(jīng)運行在ServiceA.methodA的事務內(nèi)部玄叠,就不再起新的事務。而假如ServiceA.methodA運行的時候發(fā)現(xiàn)自己沒有在事務中褂始,他就會為自己分配一個事務诸典。這樣,在ServiceA.methodA或者在ServiceB.methodB內(nèi)的任何地方出現(xiàn)異常崎苗,事務都會被回滾。即使ServiceB.methodB的事務已經(jīng)被提交舀寓,但是ServiceA.methodA在接下來fail要回滾胆数,ServiceB.methodB也要回滾
  2. PROPAGATION_SUPPORTS
    如果當前在事務中,即以事務的形式運行互墓,如果當前不再一個事務中必尼,那么就以非事務的形式運行
  3. PROPAGATION_MANDATORY
    必須在一個事務中運行。也就是說篡撵,他只能被一個父事務調(diào)用判莉。否則,他就要拋出異常``
  4. PROPAGATION_REQUIRES_NEW
    這個就比較繞口了育谬。 比如我們設計ServiceA.methodA的事務級別為PROPAGATION_REQUIRED券盅,ServiceB.methodB的事務級別為PROPAGATION_REQUIRES_NEW,那么當執(zhí)行到ServiceB.methodB的時候膛檀,ServiceA.methodA所在的事務就會掛起锰镀,ServiceB.methodB會起一個新的事務,等待ServiceB.methodB的事務完成以后咖刃,他才繼續(xù)執(zhí)行泳炉。他與PROPAGATION_REQUIRED 的事務區(qū)別在于事務的回滾程度了。因為ServiceB.methodB是新起一個事務嚎杨,那么就是存在兩個不同的事務花鹅。如果ServiceB.methodB已經(jīng)提交,那么ServiceA.methodA失敗回滾枫浙,ServiceB.methodB是不會回滾的刨肃。如果ServiceB.methodB失敗回滾,如果他拋出的異常被ServiceA.methodA捕獲自脯,ServiceA.methodA事務仍然可能提交之景。
  5. PROPAGATION_NOT_SUPPORTED
    `當前不支持事務。比如ServiceA.methodA的事務級別是PROPAGATION_REQUIRED 膏潮,而ServiceB.methodB的事務級別是PROPAGATION_NOT_SUPPORTED 锻狗,那么當執(zhí)行到ServiceB.methodB時,ServiceA.methodA的事務掛起,而他以非事務的狀態(tài)運行完轻纪,再繼續(xù)ServiceA.methodA的事務油额。
  6. PROPAGATION_NEVER
    不能在事務中運行。假設ServiceA.methodA的事務級別是PROPAGATION_REQUIRED刻帚, 而ServiceB.methodB的事務級別是PROPAGATION_NEVER 潦嘶,那么ServiceB.methodB就要拋出異常了。
  7. PROPAGATION_NESTED
    理解Nested的關(guān)鍵是savepoint崇众。他與PROPAGATION_REQUIRES_NEW的區(qū)別是掂僵,PROPAGATION_REQUIRES_NEW另起一個事務,將會與他的父事務相互獨立顷歌,而Nested的事務和他的父事務是相依的锰蓬,他的提交是要等和他的父事務一塊提交的。也就是說眯漩,如果父事務最后回滾芹扭,他也要回滾的。
    而Nested事務的好處是他有一個savepoint赦抖。

我后面還會進一步分析舱卡,先別急。在具體深入講這個傳播行為前队萤。我必須先把失效給講了轮锥。

1.事務失效的幾種可能

1、標注事務的方法不是public的

2浮禾、你的異常類型不是unchecked異常
如果我想check異常也想回滾怎么辦交胚,需要注解上面寫明異常類型即可

@Transactional(rollbackFor=Exception.class)
1
類似的還有norollbackFor,自定義不回滾的異常

3盈电、數(shù)據(jù)庫引擎要支持事務蝴簇,如果是MySQL,注意表要使用支持事務的引擎匆帚,比如innodb熬词,如果是myisam,事務是不起作用的

4吸重、是否開啟了對注解的解析

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

5互拾、spring是否掃描到你這個包,如下是掃描到org.test下面的包

<context:component-scan base-package="org.test" ></context:component-scan>

6嚎幸、檢查是不是同一個類中的方法調(diào)用(如a方法調(diào)用同一個類中的b方法)

這點非常重要颜矿,同一個類的方法調(diào)用,會導致事務無效嫉晶。

7骑疆、UNCHECKED異常是不是被你catch住了

2.為什么同一個類的方法調(diào)用會導致事務無效呢

下面這段代碼田篇,事務會失效,并不會回滾箍铭。
原因就在addUser("13522203330");
其實是this.addUser("13522203330");
而這個THIS泊柬,并不是被SPRING 用CGLIB增強的類。也就是沒有被代理诈火,自然沒有做事務了兽赁。

@Service
public class TransactionalAopServiceImpl implements TransactionalAopService {

    @Autowired
    private OrderDao orderDao;
    @Autowired
    private UserDao userDao;

    public void addOrder() {
        orderDao.insert(OrderModel.builder()
                .userId("YK_002") //游客編號
                .phone("13522203330")
                .orderId("ORDER_2018042602")
                .amount(10000L)
                .build());
        //默開用戶
        System.out.println("--->"+this.getClass());
        addUser("13522203330");
    }

    @Transactional
    public void addUser(String phone) {
        userDao.insert(UserModel.builder().userName("zhangsan").userPhone(phone).build());
        throw new RuntimeException();
    }
}

破解方法
在調(diào)用addUser(……)之前添加下面的代碼

TransactionalAopService service = (TransactionalAopService) AopContext.currentProxy(); //獲取代理對象
service.addUser("13522203330"); //通過代理對象調(diào)用addUser,做異步增強

這里還不算完冷守,如果就這樣運行刀崖,那肯定會報錯。

在@EnableAspectJAutoProxy添加屬性值拍摇。

@EnableAspectJAutoProxy(exposeProxy = true)

建議可以先看我的AOP那章蒲跨,究其源頭是在于THIS 和SERVICE 是不同的類了。
如果對代理對象和當前對象有點懵的話授翻,可以加上下面的兩行代碼:

System.out.println("------>代理對象:"+service.getClass());
System.out.println("------>當前對象:"+this.getClass());
得到的結(jié)果:

------>代理對象:class com.minuor.aop.impl.TransactionalAopServiceImpl$$EnhancerBySpringCGLIB$$9de92f4b //可以看出來是CGLB動態(tài)代理
------>當前對象:class com.minuor.aop.impl.TransactionalAopServiceImpl

情況二:addOrder和addUser方法上都添加@Transactional

這種情況下,是可以回滾的孙咪,但是不太清楚是在哪個事務回滾堪唐,也不太清楚@Transactional是都有效,還是其中一個有效翎蹈。但是可以模擬淮菠,那就是定義三個異常,分別是OrderException荤堪、UserException合陵、OtherException,然后在兩個方法上指定回滾異常類澄阳。通過拋出不同的異常來看具體的結(jié)果拥知。

@Transactional修改
@Transactional(rollbackFor = OrderException.class, noRollbackFor = RuntimeException.class) //addOrder方法上
@Transactional(rollbackFor = UserException.class, noRollbackFor = RuntimeException.class) //addUser方法上
執(zhí)行結(jié)果分析

1、拋OtherException異常碎赢,沒有回滾低剔,order、user數(shù)據(jù)都成功錄入到數(shù)據(jù)庫中肮塞;
2襟齿、拋UserException異常,沒有回滾枕赵,order猜欺、user數(shù)據(jù)都成功錄入到數(shù)據(jù)庫中,這里可以看的出來addUser方法上的@Transactional注解是無效的拷窜;
3开皿、拋OrderException異常涧黄,回滾成功,order副瀑、user數(shù)據(jù)都沒有錄入到數(shù)據(jù)庫中弓熏,addOrder方法上的@Transactional有效。
這樣的結(jié)果加上動態(tài)代理原理的分析不難得出結(jié)果糠睡,addUser方法的代理增強被繞過挽鞠,只是普通的一個方法調(diào)用,而且這個方法是包含在addOrder方法事務內(nèi)的狈孔。

3.所以事務傳播行為應該在不同類的方法間傳播信认,有了這個基礎后,我們看傳播行為的問題

1.PROPAGATION_REQUIRED
我們?yōu)閁ser1Service和User2Service相應方法加上Propagation.REQUIRED屬性均抽。

User1Service方法:

@Service
public class User1ServiceImpl implements User1Service {
    //省略其他...
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void addRequired(User1 user){
        user1Mapper.insert(user);
    }
}

User2Service方法:

@Service
public class User2ServiceImpl implements User2Service {
    //省略其他...
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void addRequired(User2 user){
        user2Mapper.insert(user);
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void addRequiredException(User2 user){
        user2Mapper.insert(user);
        throw new RuntimeException();
    }
    
}

1.1 場景一
此場景外圍方法沒有開啟事務嫁赏。

驗證方法1:

@Override
public void notransaction_exception_required_required(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequired(user2);
    
    throw new RuntimeException();
}

驗證方法2:

@Override
public void notransaction_required_required_exception(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiredException(user2);
}

分別執(zhí)行驗證方法,結(jié)果:

image.png

結(jié)論:通過這兩個方法我們證明了在外圍方法未開啟事務的情況下Propagation.REQUIRED修飾的內(nèi)部方法會新開啟自己的事務油挥,且開啟的事務相互獨立潦蝇,互不干擾。

1.2 場景二
外圍方法開啟事務深寥,這個是使用率比較高的場景攘乒。

驗證方法1:

   @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void transaction_exception_required_required(){
        User1 user1=new User1();
        user1.setName("張三");
        user1Service.addRequired(user1);
        
        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequired(user2);
        
        throw new RuntimeException();
    }

驗證方法2:

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void transaction_required_required_exception(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiredException(user2);
}

驗證方法3:

@Transactional
@Override
public void transaction_required_required_exception_try(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    try {
        user2Service.addRequiredException(user2);
    } catch (Exception e) {
        System.out.println("方法回滾");
    }
}

分別執(zhí)行驗證方法,結(jié)果:


image.png

結(jié)論:以上試驗結(jié)果我們證明在外圍方法開啟事務的情況下Propagation.REQUIRED修飾的內(nèi)部方法會加入到外圍方法的事務中惋鹅,所有Propagation.REQUIRED修飾的內(nèi)部方法和外圍方法均屬于同一事務则酝,只要一個方法回滾,整個事務均回滾闰集。

2.PROPAGATION_REQUIRES_NEW
我們?yōu)閁ser1Service和User2Service相應方法加上Propagation.REQUIRES_NEW屬性沽讹。

User1Service方法:

@Service
public class User1ServiceImpl implements User1Service {
    //省略其他...
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addRequiresNew(User1 user){
        user1Mapper.insert(user);
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void addRequired(User1 user){
        user1Mapper.insert(user);
    }
}

User2Service方法:

@Service
public class User2ServiceImpl implements User2Service {
    //省略其他...
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addRequiresNew(User2 user){
        user2Mapper.insert(user);
    }
    
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addRequiresNewException(User2 user){
        user2Mapper.insert(user);
        throw new RuntimeException();
    }
}

2.1 場景一
外圍方法沒有開啟事務。

驗證方法1:

@Override
public void notransaction_exception_requiresNew_requiresNew(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequiresNew(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiresNew(user2);
    throw new RuntimeException();
    
}

驗證方法2:

@Override
public void notransaction_requiresNew_requiresNew_exception(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequiresNew(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiresNewException(user2);
}

分別執(zhí)行驗證方法武鲁,結(jié)果:

image.png

結(jié)論:通過這兩個方法我們證明了在外圍方法未開啟事務的情況下Propagation.REQUIRES_NEW修飾的內(nèi)部方法會新開啟自己的事務爽雄,且開啟的事務相互獨立,互不干擾洞坑。

2.2 場景二
外圍方法開啟事務盲链。

驗證方法1:

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void transaction_exception_required_requiresNew_requiresNew(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiresNew(user2);
    
    User2 user3=new User2();
    user3.setName("王五");
    user2Service.addRequiresNew(user3);
    throw new RuntimeException();
}

驗證方法2:

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void transaction_required_requiresNew_requiresNew_exception(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addRequired(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addRequiresNew(user2);
    
    User2 user3=new User2();
    user3.setName("王五");
    user2Service.addRequiresNewException(user3);
}

驗證方法3:

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void transaction_required_requiresNew_requiresNew_exception_try(){
        User1 user1=new User1();
        user1.setName("張三");
        user1Service.addRequired(user1);
        
        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addRequiresNew(user2);
        User2 user3=new User2();
        user3.setName("王五");
        try {
            user2Service.addRequiresNewException(user3);
        } catch (Exception e) {
            System.out.println("回滾");
        }
    }

分別執(zhí)行驗證方法,結(jié)果:


image.png

結(jié)論:在外圍方法開啟事務的情況下Propagation.REQUIRES_NEW修飾的內(nèi)部方法依然會單獨開啟獨立事務迟杂,且與外部方法事務也獨立刽沾,內(nèi)部方法之間、內(nèi)部方法和外部方法事務均相互獨立排拷,互不干擾侧漓。

3.PROPAGATION_NESTED
我們?yōu)閁ser1Service和User2Service相應方法加上Propagation.NESTED屬性。
User1Service方法:

@Service
public class User1ServiceImpl implements User1Service {
    //省略其他...
    @Override
    @Transactional(propagation = Propagation.NESTED)
    public void addNested(User1 user){
        user1Mapper.insert(user);
    }
}

User2Service方法:

@Service
public class User2ServiceImpl implements User2Service {
    //省略其他...
    @Override
    @Transactional(propagation = Propagation.NESTED)
    public void addNested(User2 user){
        user2Mapper.insert(user);
    }
    
    @Override
    @Transactional(propagation = Propagation.NESTED)
    public void addNestedException(User2 user){
        user2Mapper.insert(user);
        throw new RuntimeException();
    }
}

3.1 場景一
此場景外圍方法沒有開啟事務监氢。

驗證方法1:

    @Override
    public void notransaction_exception_nested_nested(){
        User1 user1=new User1();
        user1.setName("張三");
        user1Service.addNested(user1);
        
        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addNested(user2);
        throw new RuntimeException();
    }

驗證方法2:

    @Override
    public void notransaction_nested_nested_exception(){
        User1 user1=new User1();
        user1.setName("張三");
        user1Service.addNested(user1);
        
        User2 user2=new User2();
        user2.setName("李四");
        user2Service.addNestedException(user2);
    }

分別執(zhí)行驗證方法布蔗,結(jié)果:


image.png

結(jié)論:通過這兩個方法我們證明了在外圍方法未開啟事務的情況下Propagation.NESTED和Propagation.REQUIRED作用相同藤违,修飾的內(nèi)部方法都會新開啟自己的事務,且開啟的事務相互獨立纵揍,互不干擾顿乒。

3.2 場景二
外圍方法開啟事務。

驗證方法1:

@Transactional
@Override
public void transaction_exception_nested_nested(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addNested(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addNested(user2);
    throw new RuntimeException();
}

驗證方法2:

@Transactional
@Override
public void transaction_nested_nested_exception(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addNested(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    user2Service.addNestedException(user2);
}

驗證方法3:

@Transactional
@Override
public void transaction_nested_nested_exception_try(){
    User1 user1=new User1();
    user1.setName("張三");
    user1Service.addNested(user1);
    
    User2 user2=new User2();
    user2.setName("李四");
    try {
        user2Service.addNestedException(user2);
    } catch (Exception e) {
        System.out.println("方法回滾");
    }
}

分別執(zhí)行驗證方法泽谨,結(jié)果:


image.png

4. REQUIRED,REQUIRES_NEW,NESTED異同

由“1.2 場景二”和“3.2 場景二”對比璧榄,我們可知:

NESTED和REQUIRED修飾的內(nèi)部方法都屬于外圍方法事務,如果外圍方法拋出異常吧雹,這兩種方法的事務都會被回滾骨杂。但是REQUIRED是加入外圍方法事務,所以和外圍事務同屬于一個事務雄卷,一旦REQUIRED事務拋出異常被回滾搓蚪,外圍方法事務也將被回滾。而NESTED是外圍方法的子事務丁鹉,有單獨的保存點妒潭,所以NESTED方法拋出異常被回滾,不會影響到外圍方法的事務揣钦。

由“2.2 場景二”和“3.2 場景二”對比杜耙,我們可知:

NESTED和REQUIRES_NEW都可以做到內(nèi)部方法事務回滾而不影響外圍方法事務。但是因為NESTED是嵌套事務拂盯,所以外圍方法回滾之后,作為外圍方法事務的子事務也會被回滾记靡。而REQUIRES_NEW是通過開啟新的事務實現(xiàn)的谈竿,內(nèi)部事務和外圍事務是兩個事務,外圍事務回滾不會影響內(nèi)部事務摸吠。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末空凸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子寸痢,更是在濱河造成了極大的恐慌呀洲,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啼止,死亡現(xiàn)場離奇詭異道逗,居然都是意外死亡,警方通過查閱死者的電腦和手機献烦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門滓窍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巩那,你說我怎么就攤上這事吏夯〈蓑冢” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵噪生,是天一觀的道長裆赵。 經(jīng)常有香客問我,道長跺嗽,這世上最難降的妖魔是什么战授? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮抛蚁,結(jié)果婚禮上陈醒,老公的妹妹穿的比我還像新娘。我一直安慰自己瞧甩,他們只是感情好钉跷,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肚逸,像睡著了一般爷辙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上朦促,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天膝晾,我揣著相機與錄音,去河邊找鬼务冕。 笑死血当,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的禀忆。 我是一名探鬼主播臊旭,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箩退!你這毒婦竟也來了离熏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤戴涝,失蹤者是張志新(化名)和其女友劉穎滋戳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啥刻,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡奸鸯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了可帽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片府喳。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蘑拯,靈堂內(nèi)的尸體忽然破棺而出钝满,到底是詐尸還是另有隱情兜粘,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布弯蚜,位于F島的核電站孔轴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碎捺。R本人自食惡果不足惜路鹰,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望收厨。 院中可真熱鬧晋柱,春花似錦、人聲如沸诵叁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拧额。三九已至碑诉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侥锦,已是汗流浹背进栽。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恭垦,地道東北人快毛。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像番挺,于是被迫代替她去往敵國和親祸泪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

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

  • 在所有使用 spring 的應用中, 聲明式事務管理可能是使用率最高的功能了, 但是, 從我觀察到的情況看, 絕大...
    我是一只小小豬閱讀 553評論 0 0
  • 很多人喜歡這篇文章建芙,特此同步過來 由淺入深談論spring事務 前言 這篇其實也要歸納到《常識》系列中,但這重點又...
    碼農(nóng)戲碼閱讀 4,719評論 2 59
  • 在Spring中懂扼,主要是通過AOP來完成聲明式的事務管理禁荸。要了解Spring對事務的支持,首先要了解事務的屬性阀湿。在...
    最深的愛最沉默_a447閱讀 576評論 0 0
  • 事務的嵌套概念 所謂事務的嵌套就是兩個事務方法之間相互調(diào)用赶熟。spring事務開啟 ,或者是基于接口的或者是基于類的...
    jackcooper閱讀 1,414評論 0 10
  • 常常有人問我搭配的技巧陷嘴,我說真沒有映砖,但我喜歡穿出我的好心情。這種美麗自己能感受到就好灾挨。
    賴世英閱讀 292評論 0 0