一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解在SpringBoot中@Transactional事物操作和事物無效問題排查

詳解在SpringBoot中@Transactional事物操作和事物無效問題排查

2021-09-18 12:08hanchao5272 Java教程

這篇文章主要介紹了詳解在SpringBoot中@Transactional事物操作和事物無效問題排查,本文詳細的介紹了SpringBoot中集成使用@Transactional注解操作事物以及事物開啟后無效的問題排查,需要的朋友可以參考下

1.spring事務管理簡述

兩種事務管理方式:

  1. 編碼式事務管理:將事務控制代碼編寫在業務代碼之中。
  2. 聲明式事務管理:基于AOP(面向切面編程),事務管理與業務邏輯解耦。聲明式事務管理的兩種實現:
    1. 在配置文件(xml)中配置。
    2. 基于@Transactional注解。

2.SpringBoot中使用@Transactional注解

2.1.開啟事務注解

在項目主類上,加上注解@EnableTransactionManagement,例如:

?
1
2
3
4
5
6
@EnableTransactionManagement
public class MySpringBootService extends WebMvcConfigurerAdapter {
    public static void main(String[] args) {
        SpringApplication.run(CoreService.class, args);
    }
}

2.2.在目標類、方法上添加注解@Transactional

1. 如果將@Transactional添加到類上,則表示此類的所有方法都開啟事務管理。如:

?
1
2
3
4
5
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
@Service
public class MyServiceImpl implements MyService {
  //class body
}

2. 如果將@Transactional添加到方法上,則表示此方法開啟事務管理。如:

?
1
2
3
4
5
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
@Override
public ActivityPo getActivityById(Long id){
  //method body
}

3. 如果一個方法上存在@Transactional,且其所屬類上同樣存在@Transactional,則以方法級別的事務配置為準。

2.3.細化事務配置

關于@Transactional的可配置參數有很多,主要有propagation、rollbackFor等,可以適用于不同場景,這里不細說。

3.@Transactional事務實現機制

3.1.整體事務控制流程

  1. 當@Transactional注解的方法被類外部的代碼調用時,Spring在運行時為方法所在類生成一個AOP代理對象。
  2. 代理對象根據@Transactional的屬性,決定是否由事務攔截器TransactionInterceptor對此方法進行事務攔截。
  3. 在進行事務攔截時,會先開啟事務,然后執行業務代碼,根據執行是否出現異常,通過抽象事務管理器AbstractPlatformTransactionManager來進行rollback或者commit。

3.2.Spring AOP的兩種代理

  1. Spring AOP有兩種CglibAopProxy和JdkDynamicAopProxy,其中:
  2. CglibAopProxy在其內部類DynamicAdvisedInterceptor的intercept()方法中,判斷是否進行事務攔截。
  3. JdkDynamicAopProxy在其invoke()方法中,判斷是否進行事務攔截。

3.3.事務操作的底層實現

  1. 抽象事務管理器AbstractPlatformTransactionManager的rollback和commit都需要具體的實現類進行實現。
  2. 抽象事務管理器AbstractPlatformTransactionManager的父級接口是PlatformTransactionManager。
  3. 存在很多事務管理器實現類,例如DataSourceTransactionManager等。
  4. 不同的事務管理器管理不同的數據資源 DataSource,比如DataSourceTransactionManager管理者JDBC數據源。
  5. 應確保被調用方法中使用的數據源都加載了事務管理器。

4.@Transactional使用注釋實現及問題排查

4.1.數據庫引擎是否支持事務?

  • MySql的引擎MyIsam不支持事務。
  • 如需事務控制生效,則庫和表的引擎必須是InnoDB。

4.3.注解所在的類是否被加載成Bean?

  • 章節3.1中第1條提到,需要在運行時為類生成代理對象。那么前提是這個類一定被Spring管理并加載成了一個Bean對象。
  • 確保所在類是否被@Component、@Service、@Controller等等注解注釋。

4.2.注解所在方法是否為public修飾的?

  • 章節3.2中,提到兩種AOP代理分別在intercept()和invoke()方法判斷是否進行事務攔截。
  • 這兩個方法都會間接調用AbstractFallbackTransactionAttributeSource類的computeTransactionAttribute方法來獲取事務控制的相關屬性。這其中有以下一段代碼:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /**
   * Same signature as {@link #getTransactionAttribute}, but doesn't cache the result.
   * {@link #getTransactionAttribute} is effectively a caching decorator for this method.
   * <p>As of 4.1.8, this method can be overridden.
   * @since 4.1.8
   * @see #getTransactionAttribute
   */
  protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
      // Don't allow no-public methods as required.
      if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
          return null;
      }
  
  //...
}
  • 這段代碼會導致no-public的方法無法進入事務控制。
  • 所以,一定要確保自己需要進行事務控制的方法包含public修飾符。

4.5.是否發生了自調用問題?

  • 章節3.1中第1條強調:只有當事務方法被當前類以外的代碼調用時,才會才由 Spring 生成的代理對象來管理。
  • 上述邏輯會造成自調用問題:當事務方法被本類內部方法調用時,@Transactional并不生效。
  • 自調用示例代碼:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Service
public class PersonServiceImpl implements PersonService{
  @Resource
  private PersonDao personDao;
  
  public void insertPerson(Person person){
    //自調用
    personService.insert(person);
    
    //其他代碼
    personDao.insertLog...
    }
  
  @Transactional(rollbackFor = Exception.class)
  public void insert(Person person){
    personDao.insert(person);
    }
}
  • 上述代碼中,如果業務邏輯從非事務方法insertPerson()開始,在其中調用了事務方法insert(),則當insert()異常時,事務控制無效。
  • 簡單說,就是在同一類中,非事務方法A調用了事務方法B,則當事務方法B異常,事務控制無效,A和B都不會回滾。
  • 那么,在同一類中,事務方法A調用了非事務方法B,然后非事務方法B調用了事務方法C,事務是否生效?答案:是。因為事務方法A在被外部代碼調用時,已經開啟了事務管理。

4.6.所用數據源是否加載了事務管理器?

  • 章節3.3中第5條提到:應確保被調用方法中使用的數據源都加載了事務管理器。
  • 在SpringBoot項目中,如果是單數據源,那么系統會默認為單數據源配置事務管理器DataSourceTransactionManager。
  • 在SpringBoot項目中,如果是多數據源,則一定確保所有的數據源都配置了事務管理器。
  • 關于多數據源的配置方法可以參考: https://blog.csdn.net/hanchao5272/article/details/81209552
  • 事務管理器的手動配置方法,可以參考如下:
?
1
2
3
4
5
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager(@Qualifier("sqlDataSource") DataSource sqlDataSource) {
  return new DataSourceTransactionManager(sqlDataSource);
}

4.4.觸發回滾的異常是否配置正確?

  • 默認情況下,事務回歸針對的是uncheck的異常(運行時異常)或ERROR。
  • 默認情況下,check的異常并不會觸發回滾,如FileNotFoundException。
  • 如果想要簡單的配置成針對所有異常都回滾,可以這么做:
?
1
@Transactional(rollbackFor = Exception.class)

4.5.@Transactional的擴展配置propagation是否正確?

  • 一般情況下,propagation屬性無需配置。其會使用默認配置,即:Propagation.REQUIRED。
  • 有些propagation屬性會導致事務不會觸發,一定要注意:
    • SUPPORTS: 如果存在事務,則進入事務;否則,以非事務方式運行。
    • NOT_SUPPORTED: 如果存在事務,則掛起事務,并以非事務方式運行。
    • NEVER: 以非事務形式運行,如果存在事務,則拋出異常。

4.7.事務管理的可選配置是否正確?

在SpringBoot中,關于事務的配置有兩個可選配置(一般無需配置):

  1. Springboot啟動類的@EnableTransactionManagement。
  2. Springboot配置文件的rollback-on-commit-failure屬性:
?
1
2
3
4
5
6
7
# yaml配置
spring:
  transaction:
    rollback-on-commit-failure: true
    
# properties配置
spring.transaction.rollback-on-commit-failure=true

請確保上述配置都是正確的(或者未配置)。

到此這篇關于詳解在SpringBoot中@Transactional事物操作和事物無效問題排查的文章就介紹到這了,更多相關SpringBoot使用@Transactional內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/hanchao5272/article/details/90343882

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
主站蜘蛛池模板: 蜜桃视频一区二区 | 夫妻性生活免费在线观看 | 草莓在线 | meyd–456佐山爱在线播放 | 青青草99久久精品国产综合 | 脱女学小内内摸出水网站免费 | 国产三级跑 | 狠狠躁夜夜躁人人爽天天miya | av72成人| 91一个人的在线观看www | 美女扒开腿让男生桶爽漫画 | 天使萌痴汉在线中文字幕 | 亚洲成人在线播放 | 国产真实伦对白在线播放 | 成人免费在线视频网 | 爱爱调教 | 91国内精品久久久久怡红院 | 美女操穴视频 | 北岛玲在线视频 | 深夜日韩 | 久久九九有精品国产23百花影院 | 丰满大乳欲妇三级k8 | 青青草色 | 欧美撒尿屁股嘘嘘撒尿 | 好吊日在线 | 亚洲视频在线观看不卡 | 日本一区二区免费在线 | 亚色九九九全国免费视频 | 四虎影院网址大全 | 双夫1v2| 国产自拍视频网站 | 秋霞理论最新三级理论最 | 国产午夜亚洲精品一区网站 | 5g影院天天爽 | 美国xaxwaswaskino| 98成人 | 男女操bb | 亚洲骚图 | 肉搏潘金莲三级18春 | 亚洲国产成人久久综合一区77 | 80s在线|