1. 程式人生 > 實用技巧 >Spring+hibernate+mysql事物不回滾的原因以及處理

Spring+hibernate+mysql事物不回滾的原因以及處理

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

最近專案突然出了點問題,然後發現用Service層下面的一個類的一個方法裡的事務居然沒有回滾。然後自己寫了一個測試方法經過了N次測試都是不回滾。以下是測試方法的一部分:

@Transactional(propagation =Propagation.REQUIRED,rollbackFor=RuntimeException.class)

public String getOnLineNum(String securecrt){
History his=new History();
his.setItem("123");

//此處特意設定一個超出欄位長度使其出錯
Ludan lu=new Ludan();
lu.setRoomName("33333333333333333");

historyDao.save(his);
ludanDao.save(lu);

return "123";
}

以上程式碼經過許多次的測試都是會把history表存入記錄,但是ludan報錯存入不了,這樣相當於事務並沒有回滾。

如下是spring的部分配置:

<!-- spring 事務管理 start-->
<bean id="transactionManager"

class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>

<!-- 宣告使用註解式事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

=====================================華麗麗的分割線============================================

一。 如上就是問題,然後經過大範圍的查閱以及搜尋,最後總結了幾點Spring事務不回滾的原因:

1.你自己捕獲異常了,沒有丟擲去讓Spring知道。

2.沒有正確配置Spring中的事務。

3.Service層次問題,即一些邏輯問題。

4.MySQL不支援事務。

二。解決辦法

這裡重點講解一下上線的第四種原因的解決辦法,這也是本人專案中遇到的問題。即MYSQL預設的資料庫模式是MyISAM,而這個模式是不支援事務的,並且在安裝mysql的時候預設的資料庫模式就是MyISAM。在mysql裡輸入:show engines;就會看到如下的畫面:

可以看到只有InnoDB才支援事務。因此要實現mysql的事務必須先把mysql資料庫模式轉換成InnoDB。

具體方法如下:

1.開啟根目錄下得my.ini檔案,在[mysqld]下加入:

default-storage-engine=INNODB

如果有skip-innodb,那就把這行注掉即可。

2.重啟mysql服務

3.再次進入mysql,輸入:show engines;就可以看到預設的資料庫模式已經是INNODB了;

4.原來存在的表則需要刪除以後再重新建一個就是INNODB的了,如果不想刪除,那就進入mysql,更新一下表引擎就可以了

執行:alter table 表名 ENGINE=InnoDB;

然後在執行:show table status from 資料庫名 where name='表名';就可以檢視狀態了

5.再次測試上面的程式碼就發現事務回滾了。

三。總結

對於這個自己遇到的問題可能是大部分人都遇到過的問題吧,也算是自己的經驗不足造成的,因此記錄下來方便一些像我一樣走在程式的路上的朋友們,希望能對大家有一些幫助,也同時做一個自己的工作記錄吧,以後也可以回來再次審查。

轉載於:https://my.oschina.net/airship/blog/832516