MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction


Mysql造成鎖的情況有很多,以下列了4種情況:

  • 執行DML操作沒有commit,再執行刪除操作就會鎖表;
  • 在同一事務內先后對同一條數據進行插入和更新操作;
  • 表索引設計不當,導致數據庫出現死鎖;
  • 長事物,阻塞DDL,繼而阻塞所有同表的后續操作。

出現事務鎖表等待,解決的辦法有四種:
(1)找出出現鎖表的事務進程殺死;
(2)進行sql語句分析,優化慢sql;
(3)把事務等待時間延長;
(4)修改表的存儲引擎為innodb。

一、找出出現鎖表的事務進程,然后將其殺死

# 查看數據庫當前正在執行的進程,只是顯示部分
show  processlist;
# 顯示所有的正在進行的進程
show full processlist; 

# 當前運行的所有事務
SELECT * FROM information_schema.INNODB_TRX;

# 當前出現的鎖
SELECT * FROM information_schema.INNODB_LOCKs;

# 鎖等待的對應關系
SELECT * FROM information_schema.INNODB_LOCK_waits;

#解釋:看事務表INNODB_TRX,里面是否有正在鎖定的事務線程,
看看ID是否在show processlist里面的sleep線程中,
如果是,就證明這個sleep的線程事務一直沒有commit或者rollback而是卡住了。
trx_mysql_thread_id  即為事務線程id。
我們需要使用kill id 命令將其殺死。

二、進行sql語句分析,優化慢sql

找到出現問題源代碼位置,然后分析一下是否存在慢sql,然后對其進行優化。最好還是檢查一下事務的使用是否使用正確,如果事務使用不正確也會導致這樣的問題。

三、延長事務超時等待時間

# 將事務超時等待的時間設置長一點 執行以下兩條sql
SET GLOBAL innodb_lock_wait_timeout = 5000; 
SET innodb_lock_wait_timeout = 5000; 

四、查看和修改表的存儲引擎

# 查看當前數據庫所支持的引擎 (mysql5.5.5以前默認是MyISAM,mysql5.5.5以后默認是InnoDB)
show ENGINES;

# 查看當前數據庫的版本
SELECT VERSION();

# 查看表使用的存儲引擎
show table status from db_name where name='table_name';

# 修改表的存儲引擎
alter table table_name engine=innodb;

參考鏈接:
(1) https://www.jianshu.com/p/0b4aaa93e7f6 (事務鎖表分析以及解決方案)
(2) https://stackoverflow.com/questions/2766785/fixing-lock-wait-timeout-exceeded-try-restarting-transaction-for-a-stuck-my/10315184 (Stack Overflow 事務鎖表解決方案)
(3)https://zhuanlan.zhihu.com/p/30743094 (show processlist 詳解)
(4)https://dev.mysql.com/doc/refman/5.6/en/general-thread-states.html (mysql官網 States 的狀態解析描述)
(5) https://ningyu1.github.io/site/post/75-mysql-lock-wait-timeout-exceeded/ (事務問題分析以及解決方案)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM