我有一个查询,我每天运行一次,从我的数据库中获取某些表并将它们放入一个表中,以便我可以快速导出我需要的任何格式的信息。
我遇到了一个问题然而却给了我以下错误:“SQLSTATE [40001]:序列化失败:1213尝试获取锁定时发现死锁;尝试重新启动事务”
根据我的理解,听起来我的查询是在已经存在锁定时尝试锁定表。但是我承认我对表锁定或它是如何工作一无所知。
我真的只是想读取其他表而不是写入它们,有没有办法可以创建查询而不是请求锁定?
我的查询非常漫长,所以我没有发布它。如果您需要某些部件让我知道,我可以发布它们。
答案 0 :(得分:2)
如果您处于事务隔离模式REPEATABLE_READ(这是默认设置),则选择不应创建任何锁。这很正常。
但是,如果你正在使用insert ...当然,你会在目标表中获得锁定。
因此,如果没有其他人正在写入目标表,并且一次只运行一个程序副本,就永远不会陷入僵局。
当两个(或更多)进程尝试执行永远无法完成的冲突事件时,会发生死锁。通常,这涉及以不同的顺序更新同一对行,但它可能取决于您的表结构。
要考虑的想法:
您可以在死锁后立即使用SHOW ENGINE INNODB STATUS查看死锁所涉及的事务。
您应该能够看到其他过程是什么以及他们在做什么。考虑打开常规日志或使用其他调试技术。
请务必在非生产系统中进行任何测试!
答案 1 :(得分:2)
您可以尝试使用INSERT DELAYED,这就是它的作用:
当客户端使用INSERT DELAYED时,它立即从服务器获得正常,并且当该表未被任何其他线程使用时,该行排队等待插入。
如果您愿意看到处于混合状态的数据,则可以更改事务隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- Problematic SELECT query goes here --
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
我从另一个SO那里得到了答案by Jon Erickson