使用预处理语句时,MySQL无法锁定表

4
在将表格锁定为可写之后尝试运行准备好的插入语句,会使得mysql出现以下错误:此命令在预处理语句协议中尚未被支持:LOCK TABLES tbl WRITE。
这个问题有没有解决的方法?正在使用INNODB引擎。
顺便说一下,我想锁定表格以避免重复插入(在应用程序端而不是数据库端进行重复检查,对于varchar(5000)来说惟一索引不适用)。因此,我需要锁定表格,但是我不能使用预处理语句来执行此操作。对于存储过程,我会得到相同的错误吗?还有其他关于此问题的想法吗?

通过锁定表,您试图解决什么问题? - N.B.
3
我会创建另一列作为唯一索引,并在其中放置一个哈希值,例如md5(your_varchar_col)或sha1 / 任何您认为适合的哈希值。这样可以避免所有表锁等问题。 - N.B.
1
请使用正确的方法在InnoDB中进行锁定 - SELECT ... FOR UPDATE - Vatev
3
MD5有2^128种可能的哈希值。在你的一生中,使用其中的百分之一都是高度不可能的。虽然MD5是一个快速算法,但你可以自由选择任何其他哈希算法。关键是,如果你聪明地使用唯一索引,就能达到相同的效果。或者你可以锁定表格,在尝试创建一个独特的varchar(5000)时,可以玩得很开心,包括未发布的锁定、存储过程和类似的好东西(为什么是5000我不知道,只需在那里使用文本类型即可)。 - N.B.
2
很抱歉在这里试图表现得过于激进,但对我来说,这种方法似乎是错误的。你基本上会为了被用作URL缩短器的高流量数据库使用写锁。为什么不允许重复?相信我,锁是你可能会遇到的最糟糕的恶魔之一,特别是当它们没有被释放并且你有几百或几千个写入排队时。根据你所说的,你可以通过使用哈希来防止重复,或者你可以简单地允许它们。 - N.B.
显示剩余5条评论
1个回答

2

使用事务,创建哈希列,并对该列放置唯一键。

正如Geo C.在他的评论中所说,您几乎肯定永远不会使用MD5发生冲突,甚至使用SHA256也更不可能。无论您生成多少个URL,即使生成数十亿个URL,在需要考虑使用锁的复杂解决方案之前,可以生成的哈希数与发生冲突的概率相比微不足道。


有时,如果你想完全避免死锁,就无法避免表锁。如果你想按顺序执行对表的UPDATE、DELETE和INSERT操作,当一个事务锁定了表索引,另一个事务锁定了主键索引并且它们互相等待时,可能会出现死锁。重新排列写操作并不总是可行的。根据使用情况,重新尝试是一种可接受的恢复技术,但通过表锁避免重试更加简洁。 - Christopher Schultz
现在,随着集群变得越来越普遍,表锁的意义越来越小,因为您无法跨集群锁定表。因此,表锁实际上不能保护您免受不得不在所有写操作上实现重试逻辑的影响,以防提交无法在整个集群中复制。因此,虽然表锁可能看起来是“正确的选择”,但从长远来看它们可能是无用的。 - Christopher Schultz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接