我试图通过hibernate同时插入(8个线程的重插入)到sql中。我的pojo由两个表组成,一个表通过外键约束引用另一个表。我试图同时将我的pojo的很多实例保存到db。由于锁等待超时,有时插入失败并回滚。
引起:java.sql.SQLException:超出锁定等待超时;尝试 重启交易。
假设有表A(屏幕截图中的表边)和表B.表B有一个外键约束,它将它的id引用到表A的主键。我可以从锁表中推断出S锁是在尝试插入表B(对应于表B的id)时,由trx 114888保持在表A的记录上,并且11493正在等待获取X锁以在表A中插入新记录。表A在其某些列上具有索引。 / p>
这里的supremum伪记录是什么意思?它是一个缺口锁吗?如果是,那么为什么记录类型为'RECORD'?有没有办法解决这个问题,以避免这种间隙锁定或任何锁定?
这些是锁定表的屏幕截图。 INNODB_LOCKS table screnshot
一些innodb状态记录
---TRANSACTION 114893, ACTIVE 2611 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 48609 lock struct(s), heap size 4726992, 585460 row lock(s), undo log entries 1132742
MySQL thread id 12620, OS thread handle 123145553027072, query id 38123782 localhost 127.0.0.1 root update
insert into edges (---some values--)
Trx read view will not see trx with id >= 114862, sees < 114817
------- TRX HAS BEEN WAITING 22 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 408 page no 135298 n bits 240 index PRIMARY of table `**database**.edges` trx id 114893 lock_mode X insert intention waiting
Record lock, heap no 1
答案 0 :(得分:0)
您正在使用可重复的读隔离级别。在可重复读取隔离级别中,使用所谓的间隙锁定并在事务持续期间保持(您可以在文档中阅读有关间隙锁定的更多信息)。如果将隔离级别从可重复读取切换为读取已提交,则问题将消失。您可以使用
设置隔离级别set transaction isolation level read committed
您应该检查命令的文档。隔离级别可以在会话级别或全局级别设置。