[英]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示例在這里的文檔中就是這樣做的......
如果有人有進一步的信息可以解釋這一點,我會很樂意將答案標記為正確答案。
但是現在,我的問題已經解決了。
編輯
回到這個月的問題后,我終於找到了它的底部。 這里有兩個主要問題。
正如Kazuki正確提到的那樣,您需要使用@Transactional(rollbackFor = Exception.class)
注釋顯式聲明需要對已檢查的異常進行@Transactional(rollbackFor = Exception.class)
。
“只有在通過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)
給出了相同的結果。
請試試這個。
謝謝。
根本原因是缺少事務管理器,因為我們明確地創建了數據源,而不依賴於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.