中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot異步與事務一起使用的問題怎么解決

發布時間:2023-05-05 14:27:59 來源:億速云 閱讀:106 作者:iii 欄目:開發技術

這篇文章主要講解了“SpringBoot異步與事務一起使用的問題怎么解決”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“SpringBoot異步與事務一起使用的問題怎么解決”吧!

最近遇到的一個場景,在一個被 @Transactional 注解的方法A中中調用了一個被 @Async 注解標記的方法B,由于方法B 在執行時方法A 的事務沒有提交,但是方法B在執行過程中獲取不到方法A中尚未提交的數據,從而最終倒是方法B執行異常。

@Transactional
public void create(User user){
  // 如果用戶已存在,則先刪除
  delete(user.id);
  // 創建用戶
  int userId = insert(user);
  //  更新用戶信息
  update(userId);
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用戶圖片
  updateUserPohot(userId,icon);
}

像上面的代碼,我為創建用戶的方法上標記了@Transactional事務注解,然后在其中調用了update()更新方法,這個方法上標記了@Async 注解。這樣代碼雖然看起來沒有什么問題,但是實際在執行update()方法時,由于是其他線程去執行的,就會導致有可能 create()方法對應的事務還沒有提交,update() 方法就無法讀取到新插入的 user 記錄,從而導致更新失敗。

解決方案

通過調整邏輯保證事務在調用異步方法前被提交

這個問題的原因是由于 @Transactional 和 @Async 注解一起使用導致的,那么我們可以從這個方向入手,首先我們可以先確認將create()方法的事務提交后,然后再去執行異步更新方法:

public void create(User user){
  int userId = doCreate(user);
  //  更新用戶信息
  update(userId);
}
@Transactional
public void doCreate(User user){
    // 如果用戶已存在,則先刪除
  delete(user.id);
  // 創建用戶
  return insert(user);
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用戶圖片
  updateUserPohot(userId,icon);
}

異步方法放在事務方法外調用,這樣異步方法就能夠讀取到已經提交的事務數據了。

或者我們還可以使用TransactionTemplate來代替 @Transactional 注解:

@Autowired
TransactionTemplate transactionTemplate;
public void create(User user){
  int userId = transactionTemplate.execute(status->{
    // 如果用戶已存在,則先刪除
    delete(user.id);
    // 創建用戶
    return insert(user);
  });
  //  更新用戶信息
  update(userId);
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用戶圖片
  updateUserPohot(userId,icon);
}

通過 TransactionTemplate細化了事務粒度,可以保證在調用異步方法前事務已經被提交。

上面的方案基本都能 解決問題,下面是從網上找到的,spring 給出的解決方案:

@Transactional
public void create(User user){
  // 如果用戶已存在,則先刪除
  delete(user.id);
  // 創建用戶
  int userId = insert(user);
  TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
    @Override
    public void afterCommit() {
      //  更新用戶信息
      update(userId);
    }
  });
}
@Async
public void update(Integer userId){
  Icon icon = getUserIcon(userId);
  // 更新用戶圖片
  updateUserPohot(userId,icon);
}

通過將異步方法注冊為事務提交后的操作,這樣Spring可以自動幫我們在事務提交后執行對應的操作。

感謝各位的閱讀,以上就是“SpringBoot異步與事務一起使用的問題怎么解決”的內容了,經過本文的學習后,相信大家對SpringBoot異步與事務一起使用的問題怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

莆田市| 宁陕县| 万盛区| 昌宁县| 商水县| 普陀区| 舟曲县| 芦山县| 瓦房店市| 玛多县| 隆回县| 乳源| 穆棱市| 德庆县| 安西县| 呼图壁县| 洪泽县| 南江县| 玛曲县| 陈巴尔虎旗| 湖南省| 南安市| 新化县| 胶南市| 大田县| 新巴尔虎右旗| 兴业县| 抚州市| 威海市| 饶阳县| 甘德县| 雷州市| 榆树市| 山阳县| 沁阳市| 杭锦后旗| 南开区| 久治县| 灌云县| 洛南县| 克山县|