一次線上MySQL死鎖告警原因排查

来源:https://www.cnblogs.com/xieshuang/archive/2022/04/01/16088083.html
-Advertisement-
Play Games

項目場景:一次線上MySQL死鎖告警原因排查 最近處理了一次線上數據告警,記錄一下。 問題描述 同步書架書籍的介面頻繁拋出異常,提示資料庫出現死鎖,異常如下: 本日異常次數:2,異常日誌:java.lang.RuntimeException: org.springframework.dao.Dead ...


項目場景:一次線上MySQL死鎖告警原因排查
最近處理了一次線上數據告警,記錄一下。

問題描述
同步書架書籍的介面頻繁拋出異常,提示資料庫出現死鎖,異常如下:

  本日異常次數:2,異常日誌:java.lang.RuntimeException: org.springframework.dao.DeadlockLoserDataAccessException: 
  ### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ### The error may involve com.iflytek.hmreader.order.dao.UBookShelfMapper.batchInsertOrUpdate-Inline
  ### The error occurred while setting parameters
  ### SQL: insert into `um_user_bookshelf` (`app_id`, `channel_id`, `version_id`, `user_id`, `book_id`, `chapter_id`, `progress`,`listened`, `from_user_id`, `create_time`,`update_time`,`sync_time`) values     (?,?,?,?,?,?,?,?,?,NOW(),?,?)  ,  (?,?,?,?,?,?,?,?,?,NOW(),?,?)  ,  (?,?,?,?,?,?,?,?,?,NOW(),?,?)  ,  (?,?,?,?,?,?,?,?,?,NOW(),?,?)   on duplicate key update chapter_id = values(chapter_id), progress = values(progress),listened = values(listened),update_time = values(update_time)
  ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  org.springframework.dao.DeadlockLoserDataAccessException: 
  ### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ### The error may involve com.iflytek.hmreader.order.dao.UBookShelfMapper.batchInsertOrUpdate-Inline
  ### The error occurred while setting parameters
  ### SQL: insert into `um_user_bookshelf` (`app_id`, `channel_id`, `version_id`, `user_id`, `book_id`, `chapter_id`, `progress`,`listened`, `from_user_id`, `create_time`,`update_time`,`sync_time`) values     (?,?,?,?,?,?,?,?,?,NOW(),?,?)  ,  (?,?,?,?,?,?,?,?,?,NOW(),?,?)  ,  (?,?,?,?,?,?,?,?,?,NOW(),?,?)  ,  (?,?,?,?,?,?,?,?,?,NOW(),?,?)   on duplicate key update chapter_id = values(chapter_id), progress = values(progress),listened = values(listened),update_time = values(update_time)
  ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:263)
  	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
  	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
  	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:447)
  	at com.sun.proxy.$Proxy70.insert(Unknown Source)
  	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:279)
  	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:56)
  	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
  	at com.sun.proxy.$Proxy115.batchInsertOrUpdate(Unknown Source)
  	at com.iflytek.hmreader.order.service.UmBookShelfServiceImpl.updBookShelf(UmBookShelfServiceImpl.java:134)
  	at com.alibaba.dubbo.common.bytecode.Wrapper10.invokeMethod(Wrapper10.java)
  	at com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:46)
  	at com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:72)
  	at com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:53)
  	at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:64)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:78)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:70)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:132)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:113)
  	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:84)
  	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:170)
  	at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)
  	at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:82)
  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  	at java.lang.Thread.run(Thread.java:748)
  Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  	at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
  	at com.mysql.jdbc.Util.getInstance(Util.java:408)
  	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:952)
  	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3976)
  	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3912)
  	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
  	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683)
  	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2486)
  	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
  	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1197)
  	at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:498)
  	at io.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor$4.executeSQL(PreparedStatementExecutor.java:158)
  	at io.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor$4.executeSQL(PreparedStatementExecutor.java:154)
  	at io.shardingsphere.core.executor.sql.execute.SQLExecuteCallback.execute0(SQLExecuteCallback.java:85)
  	at io.shardingsphere.core.executor.sql.execute.SQLExecuteCallback.execute(SQLExecuteCallback.java:69)
  	at io.shardingsphere.core.executor.ShardingExecuteEngine.syncGroupExecute(ShardingExecuteEngine.java:182)
  	at io.shardingsphere.core.executor.ShardingExecuteEngine.groupExecute(ShardingExecuteEngine.java:158)
  	at io.shardingsphere.core.executor.sql.execute.SQLExecuteTemplate.executeGroup(SQLExecuteTemplate.java:71)
  	at io.shardingsphere.core.executor.sql.execute.SQLExecuteTemplate.executeGroup(SQLExecuteTemplate.java:54)
  	at io.shardingsphere.shardingjdbc.executor.AbstractStatementExecutor.executeCallback(AbstractStatementExecutor.java:122)
  	at io.shardingsphere.shardingjdbc.executor.PreparedStatementExecutor.execute(PreparedStatementExecutor.java:161)
  	at io.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.execute(ShardingPreparedStatement.java:139)
  	at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:46)
  	at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74)
  	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50)
  	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
  	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
  	at sun.reflect.GeneratedMethodAccessor210.invoke(Unknown Source)
  	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  	at java.lang.reflect.Method.invoke(Method.java:498)
  	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
  	at com.sun.proxy.$Proxy116.update(Unknown Source)
  	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
  	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
  	at sun.reflect.GeneratedMethodAccessor209.invoke(Unknown Source)
  	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  	at java.lang.reflect.Method.invoke(Method.java:498)
  	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:434)
  	... 34 more

  	at com.alibaba.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:108)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:78)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:70)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:132)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:38)
  	at com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:91)
  	at com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:113)
  	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:84)
  	at com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:170)
  	at com.alibaba.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:52)
  	at com.alibaba.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:82)
  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  	at java.lang.Thread.run(Thread.java:748)

原因分析:
提示:這裡填寫問題的分析:

我們採用的是5.7.17版本的mysql資料庫,事務隔離級別是預設的RR(Repeatable-Read),採用innodb引擎。其中涉及的表為

CREATE TABLE um_user_bookshelf_62 (
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
app_id varchar(50) NOT NULL DEFAULT '43' COMMENT '產品ID',
channel_id varchar(50) NOT NULL DEFAULT '0' COMMENT '渠道ID',
version_id bigint(20) NOT NULL DEFAULT '0' COMMENT '版本ID',
user_id varchar(32) DEFAULT NULL,
book_id bigint(20) NOT NULL COMMENT '書籍ID',
chapter_id bigint(20) DEFAULT NULL COMMENT ' 章節編號',
progress varchar(50) DEFAULT NULL COMMENT '(閱讀/聽書)進度',
listened int(1) DEFAULT NULL COMMENT '上次是否是聽書標誌(1:看書、2:真人、3:TTS)',
from_user_id varchar(32) DEFAULT NULL COMMENT '書架資產轉移賬戶ID',
create_time datetime NOT NULL COMMENT '創建時間',
update_time datetime NOT NULL COMMENT '用戶在客戶端最後閱讀記錄時間',
sync_time datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '用戶最後獲取更新書籍記錄時間',
PRIMARY KEY (id),
UNIQUE KEY um_shelf_index_user_id_book_id (user_id,book_id) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=653275640704925698 DEFAULT CHARSET=utf8 COMMENT='用戶書架圖書記錄表';

表結構並不複雜,除去主鍵索引外還有一個唯一索引,那麼現在就去看一下MySQL的日誌,看一下在執行這個操作前後數據在執行什麼操作。這裡可以通過SHOW ENGINE INNODB STATUS來查看最近捕獲到的死鎖日誌

=====================================
2022-04-01 10:41:02 0x7f051c0c6700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 2 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 1658263 srv_active, 0 srv_shutdown, 46119058 srv_idle
srv_master_thread log flush and writes: 47773811
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 1874466
OS WAIT ARRAY INFO: signal count 1843076
RW-shared spins 0, rounds 3405123, OS waits 1707831
RW-excl spins 0, rounds 197500, OS waits 3749
RW-sx spins 1429, rounds 40856, OS waits 1194
Spin rounds per wait: 3405123.00 RW-shared, 197500.00 RW-excl, 28.59 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2022-03-31 22:10:24 0x7f051c108700
*** (1) TRANSACTION:
TRANSACTION 949308891, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 34888817, OS thread handle 139658880173824, query id 31638369 172.22.149.74 ydorder update
insert into `um_user_bookshelf_32` (`app_id`, `channel_id`, `version_id`, `user_id`, `book_id`, `chapter_id`, `progress`,`listened`, `from_user_id`, `create_time`,`update_time`,`sync_time`, id) values     ('43','201002',395,'302107202231477720',622312,2,'0',1,null,NOW(),'2021-10-23 23:18:22','1970-01-01 00:00:00', 716413229296390144), ('43','201002',395,'302107202231477720',631104,3,'195',1,null,NOW(),'2022-03-31 22:10:18','1970-01-01 00:00:00', 716413229296390145), ('43','201002',395,'302107202231477720',621438,0,'0',1,null,NOW(),'2021-10-23 23:22:19','1970-01-01 00:00:00', 716413229296390146), ('43','201002',395,'302107202231477720',675781,0,'0',1,null,NOW(),'2021-10-23 23:22:39','1970-01-01 00:00:00', 716413229296390147), ('43','201002',395,'302107202231477720',678183,0,'0',1,null,NOW(),'2021-10-23 23:23:06','1970-01-01 00:00:00', 716413229296390148), ('43','201002',395,'302107202231477720',678455,0,
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 5436 page no 63 n bits 464 index um_shelf_index_user_id_book_id of table `sharding_3`.`um_user_bookshelf_32` trx id 949308891 lock_mode X waiting
Record lock, heap no 150 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 18; hex 333032313037323032323331343737373230; asc 302107202231477720;;
 1: len 8; hex 8000000000097ee8; asc       ~ ;;
 2: len 8; hex 88ab8aab239a1004; asc     #   ;;

*** (2) TRANSACTION:
TRANSACTION 949308890, ACTIVE 0 sec inserting, thread declared inside InnoDB 4994
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 3
MySQL thread id 34888816, OS thread handle 139659922409216, query id 31638370 172.22.149.73 ydorder update
insert into `um_user_bookshelf_32` (`app_id`, `channel_id`, `version_id`, `user_id`, `book_id`, `chapter_id`, `progress`,`listened`, `from_user_id`, `create_time`,`update_time`,`sync_time`, id) values     ('43','201002',395,'302107202231477720',622312,2,'0',1,null,NOW(),'2021-10-23 23:18:22','1970-01-01 00:00:00', 716413229304774656), ('43','201002',395,'302107202231477720',631104,4,'0',1,null,NOW(),'2022-03-31 22:10:20','1970-01-01 00:00:00', 716413229304774657), ('43','201002',395,'302107202231477720',621438,0,'0',1,null,NOW(),'2021-10-23 23:22:19','1970-01-01 00:00:00', 716413229304774658), ('43','201002',395,'302107202231477720',675781,0,'0',1,null,NOW(),'2021-10-23 23:22:39','1970-01-01 00:00:00', 716413229304774659), ('43','201002',395,'302107202231477720',678183,0,'0',1,null,NOW(),'2021-10-23 23:23:06','1970-01-01 00:00:00', 716413229304774660), ('43','201002',395,'302107202231477720',678455,0,'0
*** (2) HOLDS THE LOCK(S):   事務2持有的鎖
RECORD LOCKS space id 5436 page no 63 n bits 464 index um_shelf_index_user_id_book_id of table `sharding_3`.`um_user_bookshelf_32` trx id 949308890 lock_mode X
Record lock, heap no 150 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 18; hex 333032313037323032323331343737373230; asc 302107202231477720;;
 1: len 8; hex 8000000000097ee8; asc       ~ ;;
 2: len 8; hex 88ab8aab239a1004; asc     #   ;;

Record lock, heap no 154 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 18; hex 333032313037323032323331343737373230; asc 302107202231477720;;
 1: len 8; hex 800000000009a140; asc        @;;
 2: len 8; hex 88ab8aab239a100a; asc     #   ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 5436 page no 63 n bits 464 index um_shelf_index_user_id_book_id of table `sharding_3`.`um_user_bookshelf_32` trx id 949308890 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 150 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 18; hex 333032313037323032323331343737373230; asc 302107202231477720;;
 1: len 8; hex 8000000000097ee8; asc       ~ ;;
 2: len 8; hex 88ab8aab239a1004; asc     #   ;;

*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
Trx id counter 949318674
Purge done for trx's n:o < 949318646 undo n:o < 0 state: running but idle
History list length 19
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421145291578096, not started
0 lock struct(s), heap size 1136, 0 row lock(s)

死鎖日誌的結構很清晰,主要分為兩部分 ,*** (1) TRANSACTION和*** (2) TRANSACTION,其中事務1正在執行insert操作,該操作正在申請索引um_shelf_index_user_id_book_id的X鎖(排它鎖),所以會提示lock_mode X waiting。再看事務2的部分,它持有了S鎖,併在申請lock_mode X locks gap。這裡由於是添加的是唯一索引,申請同一個X鎖造成了迴圈等待,最後由於事務1的權重比較小,被選擇了回滾。

從日誌裡面可以看出 這是個批量插入操作,兩個事物操作的數據是一樣,由於添加了userId+bookId的唯一索引,兩個事物之間會出現互相申請鎖的情況,陷入等待迴圈,造成了死鎖。到這裡可以推斷是由於併發請求導致的,然後我去翻看了一下nginx網關的訪問日誌,發現確實是這樣,同一時間 端發起了多次重覆請求,如下圖所示:

解決方案:
端調用的代碼需要排查,同時介面需要做冪等性處理。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大家好,我是棧長。 最近技術棧真是醉了,Log4j2 的核彈級漏洞剛告一段落,這個月初 Spring Cloud Gateway 又突發高危漏洞,現在連最要命的 Spring 框架也淪陷了。。。 棧長今天看到了一些安全機構發佈的相關漏洞通告,Spring 官方博客也發佈了漏洞聲明: 漏洞描述: 用戶 ...
  • 前言: 請各大網友尊重本人原創知識分享,謹記本人博客:南國以南i 上篇我們介紹到 保姆教程系列二、Nacos實現註冊中心 配置中心原理 一、 服務配置中心介紹 首先我們來看一下,微服務架構下關於配置文件的一些問題: 配置文件相對分散。在一個微服務架構下,配置文件會隨著微服務的增多變的越來越多,而且分 ...
  • Python之所以能夠成為流行的數據分析語言,有一部分原因在於其簡潔易用的字元串處理能力。 Python的字元串對象封裝了很多開箱即用的內置方法,處理單個字元串時十分方便;對於Excel、csv等表格文件中整列的批量字元串操作,pandas庫也提供了簡潔高效的處理函數,幾乎與內置字元串函數一一對應。 ...
  • 昨天凌晨發了篇關於Spring大漏洞的推文,白天就有不少小伙伴問文章怎麼刪了。 主要是因為收到朋友提醒說可能發這個會違規(原因可參考:阿裡雲因發現Log4j2核彈級漏洞但未及時上報,被工信部處罰),所以就刪除了。 經過一天的時間,似乎這個事情變得有點看不懂了。所以下麵聊聊這個網傳的Spring大漏洞 ...
  • 在學習net core中接觸到了swagger、學習並記錄 純API項目中 引入swagger可以生成可視化的API介面頁面 引入包 nuget包: Swashbuckle.AspNetCore(最新穩定版) 配置 1.配置Startup類ConfigureServices方法的相關配置 1 pub ...
  • 故事背景 在linux開發中我們經常會用到dbus來進行進程間通信,但是如何理解dbus服務端和客戶端呢?很多小伙伴可能都會遇到類似的問題,而且都是含含糊糊的,接下來我們直接上硬菜。 探索之路 首先要明白dbus是什麼,有什麼作用? 如何把自己的程式做成dbus服務? 如何調用dbus介面? 經驗心 ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 ​LNMP是Linux + Nginx + MySQL + PHP 四個系統的首字母縮寫,相對於 LAMP(Linux + Apache + MySQL + PHP )來說的。曾經在虛擬主機建站界風靡一時,隨著新的編程語言和容器技術、微服務等發展 ...
  • 我們可以通過公共倉庫拉取鏡像使用,但是,有些時候公共倉庫拉取的鏡像並不符合我們的需求。儘管已經從繁瑣的部署工作中解放出來了,但是在實際開發時,我們可能希望鏡像包含整個項目的完整環境,在其他機器上拉取打包完整的鏡像,直接運行即可。 ​ Docker 支持自己構建鏡像,還支持將自己構建的鏡像上傳到公共倉 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...