在專案中遇到因為事務沒有結束,導致插入表的操作將表給鎖住了,關於這個表的其他介面也無法訪問了。
在mysql新建查詢
show processlist;
找到超時的sql語句,找對應執行緒
通過kill該執行緒
kill trx_mysql_thread_id
通過檢視tomcat日誌發現是某個介面裡面發出http請求一直未收到響應,導致事務一直未結束,也導致該事務中的表被鎖死。然後將該http請求放到執行緒中非同步處理,解決了事務處理超時問題。應該也可以通過設定innodb_lock_wait_timeout的大小進行控制超時的時長(本人沒有實驗,檢視資料,感覺應該可以)
在搜尋表鎖死的問題看到了一些關於事務回滾的問題(雖然沒有遇到,但是也做一下小結)
如果將service的內部私有方法加上註解@transational,並不能將該方法設為乙個事務,事務不會回滾,因為spring框架裡面的事務是通過動態**實現的,如果是內部私有方法只是該類的內部例項,並不在spring的工廠裡面,只有在外部被呼叫時,才會生成動態**,所以也不會實現aop切面**。
檢視引數 innodb_rollback_on_timeout
show variables like 'innodb_rollback_on_timeout'
如果 innodb_rollback_on_timeout為on,那麼事務超時後將導致innodb終止並回滾整個事務;如果 innodb_rollback_on_timeout為off,那麼事務超時後只回滾事務超時的最後一條語句。
巢狀事務即內部,外部都有事務(如果有try catch但是沒有把異常給扔出去)
內外都無try catch,事務正常回滾
外部try catch,內部異常,正常回滾,外部異常,回滾失敗
內部有try catch,內部異常,回滾失敗,外部異常,正常回滾
內外都有try catch,內部和外部異常,回滾都失敗
正確做法是異常一定要丟擲runtimeexception
事務傳播行為型別
說明propagation_required
如果當前沒有事務,就新建乙個事務,如果已經存在乙個事務中,加入到這個事務中。這是最常見的選擇。
propagation_supports
支援當前事務,如果當前沒有事務,就以非事務方式執行
propagation_mandatory
使用當前的事務,如果當前沒有事務,就丟擲異常。
propagation_requires_new
新建事務,如果當前存在事務,把當前事務掛起。
propagation_not_supported
以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
propagation_never
以非事務方式執行,如果當前存在事務,則丟擲異常。
propagation_nested
如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行與
propagation_required類 似的操作。
關於Spring事務回滾的問題
在spring的配置檔案中,如果資料來源的defaultautocommit設定為true了,那麼方法中如果自己捕獲了異常,事務是不會回滾的,如果沒有自己捕獲異常則事務會回滾,如下例 比如配置檔案裡有這麼條記錄 那麼現在有兩個情況 情況1 如果沒有在程式中手動捕獲異常 transactional r...
spring事務回滾失效的問題
今天碰到乙個鬱悶的問題。spring配置的事務回滾無效。而且奇怪的是 中總共操作了3張表的資料,但是其中2張表在發生異常時回滾了,另一張表死活不回滾。開始還以為是事務巢狀導致的,但是搜尋一番發現spring預設的事務傳播機制是支援巢狀事務,並且發生異常會全部回滾了 這就奇了怪了,試了好幾遍仍然是其中...
Springboot 事務回滾不生效問題
檢查以下幾點 1.資料庫是否為innodb引擎 2.配置檔案中是否開啟 transaction rollback on commit failure true3.是否在啟動類中加入註解 enabletransactionmanagement4.測試問題 transactional註解必須和丟擲異常的...