最近在工作中遇到乙個問題:在對訂單做處理的時候,原本所有的業務都在乙個事務中,可操作結果是只有訂單資訊後續的所有操作都沒有,經過排查確定是mysql的事務沒有生效,所以就總結下事務失效的幾種情況
一、mysql儲存引擎引起的事務失效(一般不會遇到,目前用的mysql版本都在5.7+了)
mysql有多種儲存引擎,有些版本(mysql5.5.5以前預設是myisam,mysql5.5.5以後預設是innodb)安裝時預設的儲存引擎是myisam,而myisam儲存引擎是不支援事務處理的,所以才導致了專案中的某個方法事務失效,解決的方法就是將需要事務管理的表的儲存引擎改為innodb即可
二、非事務方法a呼叫事務b引起事務失效(**中最常見)
先看下spring事務的傳播機制:
1、propagation_required– 支援當前事務,如果當前沒有事務,就新建乙個事務。這是最常見的選擇。
2、propagation_supports– 支援當前事務,如果當前沒有事務,就以非事務方式執行。
3、propagation_mandatory– 支援當前事務,如果當前沒有事務,就丟擲異常。
4、propagation_requires_new– 新建事務,如果當前存在事務,把當前事務掛起。
5、propagation_not_supported– 以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
6、propagation_never– 以非事務方式執行,如果當前存在事務,則丟擲異常。
7、propagation_nested– 如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則進行與propagation_required類似的操作。
說明:spring預設的是propagation_required機制,如果方法a標註了註解@transactional 是完全沒問題的,執行的時候傳播給方法b,因為方法a開啟了事務,執行緒內的connection的屬性autocommit=false,並且執行到方法b時,事務傳播依然是生效的,得到的還是方法a的connection,autocommit還是為false,所以事務生效;反之,如果方法a沒有註解@transactional 時,是不受事務管理的,autocommit=true,那麼傳播給方法b的也為true,執行完自動提交,即使b標註了@transactional
事務方法之間的巢狀呼叫,普通方法和事務方法之間的巢狀呼叫,都不會開啟新的事務.是因為spring採用動態**機制來實現事務控制,而動態**最終都是要呼叫原始物件的,而原始物件在去呼叫方法時,是不會再觸發**了,所以以上就是為什麼我在沒有標註事務註解的方法a裡去呼叫標註有事務註解的方法b而沒有事務滾回的原因
//獲取**物件
sysuserservice proxyobj = (sysuserservice) aopcontext.currentproxy();
//用**物件呼叫事務方法 被呼叫方法加了事務註解
proxyobj.insertuser(user);
三、like 查詢用%開頭引起的事務失效
在使用like關鍵字進行查詢的語句中,如果匹配字串的第乙個字元為「%」,索引不會起作用。只有「%」不再第乙個位置,索引才會起作用
四、mysql在使用不等於(!=或者<>)的時候無法使用索引會導致全表掃瞄
五、is null,is not null 也無法使用索引
六、少用or,用它連線時很多情況下索引會失效
Spring boot事務失效的幾種情況
這幾天在寫專案的時候遇到了spring boot中事務失效的情況,這裡做一下記錄,後面遇到了其他情況再繼續更新。使用乙個沒有事務的方法呼叫乙個有事務的方法,失敗後不會進行回滾 transactional public intupdate admin admin public intinvokeupd...
MySQL索引失效的幾種情況
更準確的說,單列索引不儲存null值,復合索引不儲存全為null的值。索引不能儲存null,所以對這列採用is null條件時,因為索引上根本 沒null值,不能利用到索引,只能全表掃瞄。為什麼索引列不能存null值?將索引列值進行建樹,其中必然涉及到諸多的比較操作。null值的特殊性就在於參與的運...
MySQL索引失效的幾種情況
a.單列索引無法儲null值,復合索引無法儲全為null的值。b.查詢時,採用is null條件時,不能利用到索引,只能全表掃瞄。為什麼索引列無法儲存null值?a.索引是有序的。null值進入索引時,無法確定其應該放在 將索引列值進行建樹,其中必然涉及到諸多的比較操作,null 值是不確定值無法 ...