最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring事務(wù)失效問題分析及解決方案

 更新時間:2020年01月14日 10:12:33   作者:街頭賣藝的肖邦  
這篇文章主要介紹了Spring事務(wù)失效問題分析及解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

這篇文章主要介紹了Spring事務(wù)失效問題分析及解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

隔離級別

在 TransactionDefinition.java 接口中,定義了“四種”的隔離級別枚舉:

/**
 * 【Spring 獨有】使用后端數(shù)據(jù)庫默認的隔離級別
 *
 * MySQL 默認采用的 REPEATABLE_READ隔離級別
 * Oracle 默認采用的 READ_COMMITTED隔離級別
 */
int ISOLATION_DEFAULT = -1;
 
/**
 * 最低的隔離級別,允許讀取尚未提交的數(shù)據(jù)變更,可能會導(dǎo)致臟讀、幻讀或不可重復(fù)讀
 */
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
 
/**
 * 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生
 */
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
/**
 * 對同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀,但幻讀仍有可能發(fā)生。
 */
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
/**
 * 最高的隔離級別,完全服從ACID的隔離級別。所有的事務(wù)依次逐個執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說,該級別可以防止臟讀、不可重復(fù)讀以及幻讀。
 *
 * 但是這將嚴重影響程序的性能。通常情況下也不會用到該級別。
 */
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;

事務(wù)的傳播級別

事務(wù)的傳播行為,指的是當前帶有事務(wù)配置的方法,需要怎么處理事務(wù);例如:方法可能繼續(xù)在現(xiàn)有事務(wù)中運行,也可能開啟一個新事務(wù),并在自己的事務(wù)中運行;

需要注意,事務(wù)的傳播級別,并不是數(shù)據(jù)庫事務(wù)規(guī)范中的名詞,而是 Spring 自身所定義的。通過事務(wù)的傳播級別,Spring 才知道如何處理事務(wù),是創(chuàng)建一個新事務(wù)呢,還是繼續(xù)使用當前的事務(wù);

在 TransactionDefinition.java 接口中,定義了三類七種傳播級別:

// ========== 支持當前事務(wù)的情況 ==========
 
/**
 * 如果當前存在事務(wù),則使用該事務(wù)。
 * 如果當前沒有事務(wù),則創(chuàng)建一個新的事務(wù)。
 */
int PROPAGATION_REQUIRED = 0;
/**
 * 如果當前存在事務(wù),則使用該事務(wù)。
 * 如果當前沒有事務(wù),則以非事務(wù)的方式繼續(xù)運行。
 */
int PROPAGATION_SUPPORTS = 1;
/**
 * 如果當前存在事務(wù),則使用該事務(wù)。
 * 如果當前沒有事務(wù),則拋出異常。
 */
int PROPAGATION_MANDATORY = 2;
 
// ========== 不支持當前事務(wù)的情況 ==========
 
/**
 * 創(chuàng)建一個新的事務(wù)。
 * 如果當前存在事務(wù),則把當前事務(wù)掛起。
 */
int PROPAGATION_REQUIRES_NEW = 3;
/**
 * 以非事務(wù)方式運行。
 * 如果當前存在事務(wù),則把當前事務(wù)掛起。
 */
int PROPAGATION_NOT_SUPPORTED = 4;
/**
 * 以非事務(wù)方式運行。
 * 如果當前存在事務(wù),則拋出異常。
 */
int PROPAGATION_NEVER = 5;
 
// ========== 其他情況 ==========
 
/**
 * 如果當前存在事務(wù),則創(chuàng)建一個事務(wù)作為當前事務(wù)的嵌套事務(wù)來運行。
 * 如果當前沒有事務(wù),則等價于 {@link TransactionDefinition#PROPAGATION_REQUIRED}
 */
int PROPAGATION_NESTED = 6;

@Transaction

@Transaction 注解是Spring的tx模塊提供的,使用AOP實現(xiàn)的事務(wù)控制,即底層為動態(tài)代理;

  @Transaction 可以作用于接口、接口方法、類以及類方法上;當作用于類上時,該類的所有 public 方法將都具有該類型的事務(wù)屬性,也可以在方法級別使用該標注來覆蓋類級別的定義;

  事務(wù)失效

  1.異常類型錯誤,默認是RuntimException才會回滾

  2.異常被catch后沒有拋出,需要拋異常才能回滾

  3.是否發(fā)生自身調(diào)用的問題

  4.注解所在位置是否為public修飾

  5.數(shù)據(jù)源沒有配置事務(wù)管理器

  6.不支持事務(wù)的引擎,如MyIsam

  下面是一個事務(wù)失效的例子

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
  @Autowired
  private OrderMapper orderMapper;
 
  @Transactional
  @Override
  public void parent() {
    try {
      this.child();
 
    } catch (Exception e) {
      log.error("插入異常", e);
    }
 
 
    Order order = new Order();
    order.setOrderNo("parent");
    order.setStatus("0");
    order.setTitle("parent");
    order.setAmount("1000");
    orderMapper.insert(order);
  }
 
 
  @Transactional
  @Override
  public void child() {
 
    Order order = new Order();
    order.setOrderNo("child");
    order.setStatus("0");
    order.setTitle("child");
    order.setAmount("2000");
    orderMapper.insert(order);
 
    throw new RuntimeException();
  }
}

當調(diào)用parent方法時,會調(diào)用child方法,但執(zhí)行完成后插入的記錄有兩條,一條是parent的,一條是child的;

這是因為上面的parent方法調(diào)用的child方法出現(xiàn)問題,@Transaction 是基于AOP的方式進行事務(wù)控制的(CglibAopProxy.java進行方法攔截,TransactionInterceptor.java進行代理對象調(diào)用執(zhí)行方法),需要使用的是代理對象調(diào)用方法,上面的代碼使用的還是this,即當前實例化對象,因此執(zhí)行this.child(),方法不能被攔截增強;

將上面的parent方法修改如下

@Autowired
private ApplicationContext context;
 
private OrderService orderService;
 
@PostConstruct
public void init() {
  orderService = context.getBean(OrderService.class);
}
 
 
@Transactional
@Override
public void parent() {
  try {
    //獲取代理對象,通過代理對象調(diào)用child()
    orderService.child();
 
   //獲取代理對象
    //OrderService orderService = (OrderService) AopContext.currentProxy();
    //orderService.child();
  } catch (Exception e) {
    log.error("插入異常", e);
  }
  Order order = new Order();
  order.setOrderNo("parent");
  order.setStatus("0");
  order.setTitle("parent");
  order.setAmount("1000");
  orderMapper.insert(order);
}

執(zhí)行parent方法,當出現(xiàn)異常的時候,事務(wù)會進行回滾;

如果想實現(xiàn)當調(diào)用parent方法時,調(diào)用child方法發(fā)生異常,只回滾child方法插入的數(shù)據(jù),parent方法插入的數(shù)據(jù)不回滾,修改如下

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void child() {
 
  Order order = new Order();
  order.setOrderNo("child");
  order.setStatus("0");
  order.setTitle("child");
  order.setAmount("2000");
  orderMapper.insert(order);
 
  throw new RuntimeException();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)

如果當前存在事務(wù),則掛起事務(wù)并開啟一個新事務(wù)執(zhí)行,新事務(wù)執(zhí)行完畢后,喚醒之前的掛起的事務(wù),則繼續(xù)執(zhí)行;如果當前不存在事務(wù),則新建一個事務(wù);

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用springmvc配置視圖解析器和重定向方式

    使用springmvc配置視圖解析器和重定向方式

    這篇文章主要介紹了使用springmvc配置視圖解析器和重定向方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java Swing實現(xiàn)簡單的體重指數(shù)(BMI)計算器功能示例

    Java Swing實現(xiàn)簡單的體重指數(shù)(BMI)計算器功能示例

    這篇文章主要介紹了Java Swing實現(xiàn)簡單的體重指數(shù)(BMI)計算器功能,涉及Java Swing窗口組件布局、響應(yīng)及數(shù)值運算相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • Java日期工具類時間校驗實現(xiàn)

    Java日期工具類時間校驗實現(xiàn)

    一般項目中需要對入?yún)⑦M行校驗,比如必須是一個合法的日期,本文就來介紹一下Java日期工具類時間校驗實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • SpringBoot實現(xiàn)自定義配置文件提示的方法

    SpringBoot實現(xiàn)自定義配置文件提示的方法

    這篇文章主要介紹了SpringBoot實現(xiàn)自定義配置文件提示的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java8?Stream流多字段求和、匯聚的實例

    Java8?Stream流多字段求和、匯聚的實例

    這篇文章主要介紹了Java8?Stream流多字段求和、匯聚的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 如何利用grep-console插件使Intellij idea顯示多顏色調(diào)試日志

    如何利用grep-console插件使Intellij idea顯示多顏色調(diào)試日志

    這篇文章主要介紹了利用grep-console插件使Intellij idea顯示多顏色調(diào)試日志,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • JSON,AJAX,Maven入門基礎(chǔ)

    JSON,AJAX,Maven入門基礎(chǔ)

    這篇文章主要介紹了JSON,AJAX和Maven基礎(chǔ),如何使用AJAX讀取Json數(shù)組里面的數(shù)據(jù),感興趣的小伙伴們可以參考一下,希望能夠幫助到你
    2021-07-07
  • 簡單了解Mybatis如何實現(xiàn)SQL防注入

    簡單了解Mybatis如何實現(xiàn)SQL防注入

    這篇文章主要介紹了簡單了解Mybatis如何實現(xiàn)SQL防注入,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • 詳解Javaee Dao層的抽取

    詳解Javaee Dao層的抽取

    這篇文章主要介紹了詳解Javaee Dao層的抽取,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Java后臺實現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包

    Java后臺實現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包

    這篇文章主要為大家詳細介紹了Java后臺實現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07

最新評論

正蓝旗| 昌吉市| 陇南市| 志丹县| 长武县| 澄城县| 台湾省| 盐亭县| 大渡口区| 丁青县| 杭锦旗| 门源| 易门县| 京山县| 德清县| 万全县| 汉寿县| 越西县| 嘉鱼县| 化德县| 孟州市| 无极县| 恩施市| 咸阳市| 宁陕县| 桐柏县| 桓台县| 忻城县| 吴川市| 大名县| 西乌珠穆沁旗| 科技| 长岭县| 裕民县| 江阴市| 长垣县| 股票| 阜城县| 平阴县| 巩留县| 南昌市|