简体   繁体   English

MYSQL INNODB手动加锁

[英]MYSQL INNODB Manual Increment with locking

ID|RID|SID|Name
 1| 1 | 1 |Alpha
 2| 1 | 2 |Beta
 3| 2 | 1 |Charlie

ID is auto-incrementing unique, not the problem here. ID是自动递增的唯一值,这里不是问题。 RID is grouping sets of data together, I need a way to make the SID unique per RID 'group'. RID将数据集分组在一起,我需要一种方法来使每个RID“组”的SID唯一。 This structure is correct, I anticipate someone saying 'split it into multiple tables', that's not an option here (it's taxonomic classification). 这种结构是正确的,我希望有人说“将其拆分成多个表”,这里不是一种选择(它是分类学分类)。

As shown, under RID 1, the SID increments from 1 to 2, but when the RID changes to 2, the SID is 1. 如图所示,在RID 1下,SID从1递增到2,但是当RID更改为2时,SID为1。

I have the code to get the next value: SELECT IFNULL(MAX(SID),0)+1 AS NextVal FROM t WHERE RID=1 , the question is how do I use that value when inserting a new record? 我有获取下一个值的代码: SELECT IFNULL(MAX(SID),0)+1 AS NextVal FROM t WHERE RID=1 ,问题是在插入新记录时如何使用该值?

I can't simply run two queries as that can result in duplication, so somehow the table needs to be locked, ideally to write only. 我不能简单地运行两个查询,因为这可能导致重复,因此需要以某种方式锁定表,理想情况下只写表。 What would be the correct way to do this? 正确的方法是什么?

At first you should constraint your data to be exactly the way you want it to be, so put an unique combined index on (RID, SID) . 首先,应将数据严格限制为您想要的数据,因此在(RID, SID)上放置一个唯一的组合索引。

For your problem you should start a transaction ( BEGIN ) and then put an exclusive lock onto the rows you need, which blocks all access to these rows for other connections (not the whole table, which is poor for performance!): 对于您的问题,您应该启动一个事务( BEGIN ),然后在所需的行上设置排他锁,这将阻止其他连接对这些行的所有访问(而不是对性能不好的整个表!):

SELECT .... FOR UPDATE

This locks all selected rows exclusively. 这将锁定所有选定的行。 Further you should not use READ UNCOMMITTED as isolation level. 而且你应该使用READ UNCOMMITTED隔离级别。 you can view in the manual how to check the current isolation level and how to change this. 您可以在手册中查看如何检查当前隔离级别以及如何更改此级别。 REPEATABLE READ is the default isolation level, which would be fine here. REPEATABLE READ是默认的隔离级别,在这里可以使用。

Then insert your new query and commit ( COMMIT ) the transaction. 然后插入新查询并提交( COMMIT )事务。

This should prohibit duplicates altogether since you created an unique index and it should also prohibit your scripts just failing with an error message that the unique check failed, but instead wait for other scripts to finish and insert the next row then. 这应该完全禁止重复,因为您创建了唯一索引,并且还应该禁止脚本以唯一检查失败的错误消息失败,而是等待其他脚本完成并插入下一行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM