mysql事物sql语句死锁,定时任务启动失败Lock wait timeout exceeded;try restarting transaction

把定时任务quartz配置mysql里多台机器启动时可能会出现数据库死锁,然后控制台报错:

Lock wait timeout exceeded;try restarting transaction

项目启动失败,这时候只需要去mysql中查两个语句,然后杀掉对应的死锁线程就行:

1.查询mysql所有正在执行的sql,看到query就说明是正在执行的,有时候慢查询导致程序卡住无响应也可以这么查杀
show processlist;
kill id;
2.查看mysql事物表INNODB_TRX,在information_schema库中
SELECT * FROM information_schema.innodb_trx ;
kill trx_mysql_thread_id;
杀掉死锁的事务线程重新启动项目。
MySQL 中执行 `INSERT` 语句时,如果出现如下错误: ``` Lock wait timeout exceeded; try restarting transaction ``` 这个错误表示当前事务在等待某个行锁(InnoDB 行锁)时超时了(默认等待时间为 **50 秒**)。这通常发生在**高并发**或**事务未及时提交**的情况下。 --- ## 一、错误原因详解 ### 1. **行锁冲突(Row Lock)** - InnoDB 是支持行级锁的存储引擎。 - 当两个事务同时尝试修改同一行数据时,一个事务必须等待另一个事务释放锁。 - 如果等待时间超过 `innodb_lock_wait_timeout`(默认 50 秒),就会抛出该异常。 ### 2. **事务未提交** - 某个事务执行了 `INSERT`、`UPDATE` 或 `DELETE` 操作,但没有 `COMMIT` 或 `ROLLBACK`。 - 其他事务在访问相同数据时就会被阻塞,直到锁释放。 ### 3. **长事务** - 一个事务执行时间很长(如嵌套循环、大量数据处理),导致其他事务长时间等待。 ### 4. **死锁** - 虽然死锁通常由 MySQL 自动检测并回滚其中一个事务,但在某些情况下也可能表现为锁等待超时。 --- ## 二、解决方法 ### ✅ 方法 1:查看当前事务状态和锁等待情况 ```sql -- 查看当前事务 SELECT * FROM information_schema.innodb_trx; -- 查看锁等待情况 SELECT * FROM information_schema.innodb_locks; -- 查看锁等待详细信息 SELECT * FROM performance_schema.data_locks; ``` ### ✅ 方法 2:优化事务提交逻辑 - **减少事务执行时间**,避免在事务中做耗时操作。 - **及时提交事务**,不要长时间保持事务打开状态。 ```java // 示例:Java 中使用 JDBC 提交事务 Connection conn = dataSource.getConnection(); try { conn.setAutoCommit(false); PreparedStatement ps = conn.prepareStatement("INSERT INTO users (name, email) VALUES (?, ?)"); ps.setString(1, "Alice"); ps.setString(2, "alice@example.com"); ps.executeUpdate(); conn.commit(); // 及时提交 } catch (SQLException e) { conn.rollback(); // 出错回滚 } finally { conn.setAutoCommit(true); conn.close(); } ``` ### ✅ 方法 3:调整 `innodb_lock_wait_timeout` - 如果你确实需要较长的等待时间,可以适当增加该值(不推荐长期使用)。 ```sql SET innodb_lock_wait_timeout = 120; -- 设置为 120 秒 ``` 也可以在 `my.cnf` 中永久设置: ```ini [mysqld] innodb_lock_wait_timeout=120 ``` ### ✅ 方法 4:避免并发写冲突 - 对热点数据(如计数器、订单表)进行分片处理。 - 使用乐观锁机制(如版本号)。 ```sql -- 使用版本号实现乐观锁更新 UPDATE users SET name = 'Alice', version = version + 1 WHERE id = 1 AND version = 3; ``` ### ✅ 方法 5:分析慢查询日志 开启慢查询日志,找出执行时间长的 SQL: ```ini [mysqld] slow_query_log = 1 long_query_time = 1 slow_query_log_file = /var/log/mysql/slow.log ``` --- ## 三、示例:事务未提交导致锁等待 ```sql -- 会话 1 START TRANSACTION; UPDATE users SET name = 'Alice' WHERE id = 1; -- 会话 2 START TRANSACTION; UPDATE users SET name = 'Bob' WHERE id = 1; -- 这里会等待锁释放 -- 如果等待超过 50 秒,报错Lock wait timeout exceeded ``` --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值