Spring事務(wù)失效的原因及解決方案
一、spring方法調(diào)用導(dǎo)致事務(wù)失效原因
1、事務(wù)失效場景復(fù)現(xiàn)
1.1 背景原因
在循環(huán)中處理事務(wù)問題上,我們使用聲明式事務(wù)有以下選擇:
1.1.1 把@Transanal注解放在整個(gè)循環(huán)的方法上,這樣整個(gè)循環(huán)都會(huì)被spring事務(wù)管理到,缺點(diǎn)是使用了長事務(wù),會(huì)導(dǎo)致鎖表問題,影響效率。
1.1.2 將每一次循環(huán)抽出一個(gè)方法,把@Transanal注解加在這個(gè)方法上。這樣spring只管理了本次循環(huán)的事務(wù),解決了長事務(wù)問題,但是有事務(wù)失效的風(fēng)險(xiǎn)。
1.2 場景模擬
@Repository
public class BookDao {
@Transactional(propagation = Propagation.REQUIRED)
public void updateStock(int id){
String sql = "update book_stock set stock=stock-1 where id=?";
jdbcTemplate.update(sql,id);
for (int i = 1 ;i>=0 ;i--)
System.out.println(10/i);
}
public void test(){
this.updateStock(1);
}
}updateStock方法上@Transanal,會(huì)將updateStock方法交給spring事務(wù)管理;
test方法上無@Transanal,test方法不會(huì)交給spring事務(wù)管理。
測試的時(shí)候調(diào)用test方法的時(shí)候,發(fā)現(xiàn)test內(nèi)部調(diào)用的updateStock時(shí),updateStock的事務(wù)失效了;因?yàn)閠est內(nèi)部調(diào)用的updateStock方法只是BookDao原對(duì)象的的原方法,而不是BookDao被代理對(duì)象的方法,所以事務(wù)失效
2、解決方案
通過事務(wù)失效的原因分析可知,我們只有調(diào)用代理對(duì)象的方法才會(huì)走事務(wù)
2.1 方法一
從容器中取出代理類,調(diào)用它的代理方法??梢酝ㄟ^實(shí)現(xiàn)ApplicationContextAware接口,獲取IOC容器applicationContext對(duì)象,從容器中獲取BookDao代理對(duì)象
@Repository
public class BookDao implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
applicationContext = applicationContext;
}
public void test(){
BookDao bookDao = applicationContext.getBean(BookDao.class);
bookDao.updateStock(1);
}
@Transactional(propagation = Propagation.REQUIRED)
public void updateStock(int id){
String sql = "update book_stock set stock=stock-1 where id=?";
jdbcTemplate.update(sql,id);
for (int i = 1 ;i>=0 ;i--)
System.out.println(10/i);
}
}2.1 方法二
使用AOP暴露出來的代理對(duì)象,其本質(zhì)也跟上面的一樣,在啟動(dòng)類上加@EnableAspectJAutoProxy(exposeProxy = true),方法調(diào)用通過AopContext.currentProxy()獲取代理對(duì)象
public void test(){
BookDao bookDao = ( BookDao)AopContext.currentProxy();
// BookDao bookDao = applicationContext.getBean(BookDao.class);
bookDao.updateStock(1);
}到此這篇關(guān)于Spring事務(wù)失效的原因及解決方案的文章就介紹到這了,更多相關(guān)Spring事務(wù)失效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot響應(yīng)出現(xiàn)中文亂碼的解決方法
這篇文章主要介紹了SpringBoot響應(yīng)出現(xiàn)中文亂碼的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起來學(xué)習(xí)吧2024-02-02
IDEA SSM整合Redis項(xiàng)目實(shí)例 附源碼
今天給大家普及IDEA SSM整合Redis項(xiàng)目實(shí)例,包括pom.xml 配置和spring-redis.xml 配置代碼,代碼也很簡單,通過項(xiàng)目實(shí)際案例能更好的幫助大家理解,需要的朋友可以參考下2021-06-06
基于JavaSwing設(shè)計(jì)和實(shí)現(xiàn)的酒店管理系統(tǒng)
這篇文章主要介紹了基于JavaSwing+mysql的酒店管理系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn),它可以實(shí)現(xiàn)酒店日常的管理功能包括開房、退房、房間信息、顧客信息管理等2021-08-08
Spring 4.0新功能:@Conditional注解詳細(xì)介紹
Spring Boot的強(qiáng)大之處在于使用了Spring 4框架的新特性:@Conditional注釋,此注釋使得只有在特定條件滿足時(shí)才啟用一些配置。下面這篇文章主要給大家介紹了關(guān)于Spring4.0中新功能:@Conditional注解的相關(guān)資料,需要的朋友可以參考下。2017-09-09
Java利用遞歸實(shí)現(xiàn)樹形結(jié)構(gòu)的工具類
有時(shí)候,我們的數(shù)據(jù)是帶有層級(jí)的,比如常見的省市區(qū)三級(jí)聯(lián)動(dòng),就是一層套著一層。而我們?cè)跀?shù)據(jù)庫存放數(shù)據(jù)的時(shí)候,往往是列表形式的,這個(gè)時(shí)候可能就需要遞歸處理為樹形結(jié)構(gòu)了。本文就為大家介紹了Java利用遞歸實(shí)現(xiàn)樹形結(jié)構(gòu)的工具類,希望對(duì)大家有所幫助2023-03-03

