簡體   English   中英

Spring Transaction Management無法使用Spring Boot + MyBatis?

[英]Spring Transaction Management not working with Spring Boot + MyBatis?

我試圖讓Spring Transaction Management在我的新Spring Boot + MyBatis應用程序中運行。

到目前為止,我已經設法讓所有事情都處理最少的問題 - 它只是讓@Transactional注釋正常運行。 目前,無論方法是否注釋,都會立即提交所有語句。

Spring Boot為您提供了大量的樣板配置,因此很難找到缺失的鏈接。

我的build.gradle包含以下依賴項:

compile("org.springframework.boot:spring-boot-starter-amqp")
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:1.0.0")
compile("mysql:mysql-connector-java:5.1.38")

我的application.properties包含以下數據源配置:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/my_db
spring.datasource.username=my_user
spring.datasource.password=my_pass

bean中未按預期運行的方法的簡單示例如下:

@Transactional
public void performTransactionTest() throws Exception {

    Person person = new Person();
    person.setPersonId(123);
    personMapper.insert(person);

    throw new Exception("This should force a rollback!");

}

拋出異常但已插入記錄。

目前Spring Boot和MyBatis的事務配置基本上沒有文檔存在,但據我所知,它應該主要用自己的方式連接起來,就像在Spring + MyBatis應用程序中手動完成一樣,它沒有 - 我們是能夠進一步配置它。 有了這個說我在applicationContext.xml嘗試了以下配置而沒有運氣:

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

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
</bean>

我可以確認,即使沒有上述任何配置,DataSourceTransactionManager也配置了與MyBatis映射器的SqlSession使用的相同的DataSource。

任何有助於我朝着正確方向前進的幫助或想法都將不勝感激。 如果您需要任何進一步的信息,我很樂意提供!

提前致謝!

Xandel

所以我通過使用@Transactional而不是方法定義來注釋類定義來實現它。

我不確定這是否是常見做法。 Spring Boot事務管理文檔不像這里那樣,但是Mybatis Spring示例在這里的文檔中就是這樣做的......

如果有人有進一步的信息可以解釋這一點,我會很樂意將答案標記為正確答案。

但是現在,我的問題已經解決了。

編輯

回到這個月的問題后,我終於找到了它的底部。 這里有兩個主要問題。

  1. 正如Kazuki正確提到的那樣,您需要使用@Transactional(rollbackFor = Exception.class)注釋顯式聲明需要對已檢查的異常進行@Transactional(rollbackFor = Exception.class)

  2. “只有在通過Spring代理調用正確注釋的方法時才會創建事務邊界。這意味着您需要直接通過@Autowired bean調用帶注釋的方法,否則事務將永遠無法啟動。” (參考下面這個來源)

在我的示例代碼中,我從同一個類中調用this.performTransactionTest() 這樣,交易將被忽略。 如果我通過對我的類的有線引用myAutoWiredBean.performTransactionTest()例如myAutoWiredBean.performTransactionTest()調用它,一切都按預期工作。 這也解釋了為什么只有類級別注釋才起作用,但這是因為任何被調用的方法都會被有線bean引用。

有兩篇文章是我在幫助我理解Spring交易管理的細節方面的主要幫助。 非常感謝作者Nitin Prabhu和Tim Mattison。

https://dzone.com/articles/spring-transaction-management

http://blog.timmattison.com/archives/2012/04/19/tips-for-debugging-springs-transactional-annotation/

我希望這有助於某人!

Spring Transaction Management默認行為是在發生檢查的異常時提交。 如果要回滾事務,可以拋出未經檢查的異常( RuntimeException )。 另外@Transactional(rollbackFor = Exception.class)給出了相同的結果。

請試試這個。

有關詳細信息,請參閱https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-rolling-back

謝謝。

根本原因是缺少事務管理器,因為我們明確地創建了數據源,而不依賴於spring boot來根據application.yml參數自動創建。 此外,不需要注釋類而是注釋下面的方法並在啟動期間初始化事務管理器bean。

@Transactional(propagation = Propagation.REQUIRED, transactionManager = "transactionManager", rollbackFor = CustomExcp.class)
public int updt(Emp vo) throws CustomExcp {
...
}

@Bean
    public DataSourceTransactionManager transactionManager() {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        log.info("DataSource Transaction Manager");
        return transactionManager;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM