1. 程式人生 > 實用技巧 >Mybatis關聯對映(一對一)

Mybatis關聯對映(一對一)

問題現象:

  介面響應時間超長,耗時幾十秒才返回錯誤提示,後臺日誌中出現Lock wait timeout exceeded; try restarting transaction的錯誤

問題場景:

  1、在同一事務內先後對同一條資料進行插入和更新操作;

  2、多臺伺服器操作同一資料庫;

  3、瞬時出現高並發現象;

問題原因:

  1、在高併發的情況下,Spring事物造成資料庫死鎖,後續操作超時丟擲異常。

  2、資料庫採用InnoDB模式,預設引數:innodb_lock_wait_timeout設定鎖等待的時間是50s,一旦資料庫鎖超過這個時間就會報錯

解決方法:

1、檢視資料庫當前的程序,看一下有無正在執行的慢SQL記錄執行緒。

mysql> show  processlist;

2、檢視當前的事務

當前執行的所有事務

mysql> SELECT * FROM information_schema.INNODB_TRX;

當前出現的鎖

mysql> SELECT * FROM information_schema.INNODB_LOCKs;

鎖等待的對應關係

mysql> SELECT * FROM information_schema.INNODB_LOCK_waits;

解釋:看事務表INNODB_TRX,裡面是否有正在鎖定的事務執行緒,看看ID是否在show processlist裡面的sleep執行緒中,如果是,就證明這個sleep的執行緒事務一直沒有commit或者rollback而是卡住了,我們需要手動kill掉。

搜尋的結果是在事務表發現了很多工,這時候最好都kill掉。

3、批量刪除事務表中的事務

我這裡用的方法是:通過information_schema.processlist表中的連線資訊生成需要處理掉的MySQL連線的語句臨時檔案,然後執行臨時檔案中生成的指令。

mysql>  select concat('KILL ',id,';') from information_schema.processlist where user='cms_bokong';
+------------------------+
| concat('KILL ',id,';') |
+------------------------+
| KILL 10508;            |
| KILL 10521;            |
| KILL 10297;            |
+------------------------+
18 rows in set (0.00 sec)

當然結果不可能只有3個,這裡我只是舉例子。參考連結上是建議匯出到一個文字,然後執行文字。而我是直接copy到記事本處理掉 ‘|’,貼上到命令列執行了。都可以。

kill掉以後再執行SELECT * FROM information_schema.INNODB_TRX; 就是空了。

這時候系統就正常了

故障排查

  1. mysql都是autocommit配置mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 0 | +--------------+ 1 row in set (0.00 sec)

如果是0 ,則改為1

mysql> set global autocommit=1;

  1. mysql的引擎檢查,可以檢查一下資料庫引擎是不是InnoDB(mysql5.5.5以前預設是MyISAM,mysql5.5.5以後預設是InnoDB)show ENGINES; #檢查命令 如果不是的話改為 InnoDB :

查看錶使用的儲存引擎

show table status from db_name where name='table_name';

修改表的儲存引擎

alter table table_name engine=innodb;

 

 轉載至:https://cloud.tencent.com/developer/article/1356959