mybatis BatchUpdateException: Lock wait timeout exceeded; try restarting transaction
时间: 2025-01-03 16:40:15 浏览: 27
### MyBatis 批量更新时遇到的锁等待超时解决方案
在使用 MyBatis 进行批量更新操作时,如果遇到了 `BatchUpdateException` 和锁等待超时问题,通常是因为数据库中的事务管理不当或并发控制机制设置不合理所致。以下是几种可能的原因及相应的解决方法:
#### 调整 InnoDB 锁等待时间
InnoDB 存储引擎默认情况下会有一个固定的锁等待超时时间,在高并发场景下容易触发此限制。可以通过修改配置文件来增加该参数值,从而减少因短暂争用资源而引发的异常情况。
```sql
SET GLOBAL innodb_lock_wait_timeout = 500;
```
这将全局范围内把最大允许等待的时间调整为 500 秒[^4]。
#### 使用乐观锁策略
对于频繁发生冲突的数据表可以考虑引入版本号字段(version),每次更新记录前先读取当前最新版本号并加一提交给 SQL 语句作为条件之一;只有当所指定版本号匹配成功才会真正执行写入动作,否则返回错误提示用户重试。
```xml
<update id="updateUser">
UPDATE users SET name=#{name}, version=version+1 WHERE id=#{id} AND version=#{currentVersion}
</update>
```
这种方法能够有效降低死锁发生的概率,并且提高了系统的吞吐能力[^1]。
#### 减少单次批量操作规模
适当拆分大批次任务成多个较小单元分别处理,这样不仅有助于缓解瞬时压力还能让应用程序更好地应对部分失败的情况而不至于全部回滚重做整个流程。
```java
int batchSize = 100; // 设置合适的批大小
for (int i = 0; i < list.size(); i += batchSize) {
List<User> sublist = list.subList(i, Math.min(i + batchSize, list.size()));
sqlSession.update("batchUpdateUsers", sublist);
}
```
通过以上措施可以在很大程度上改善由锁竞争引起的各种性能瓶颈以及稳定性方面的问题[^2]。
阅读全文