简体   繁体   English

锁定表以从 MySQL InnoDB 存储过程插入

[英]Locking a table for inserts from a MySQL InnoDB Stored Procedure

I am writing a stored procedure.我正在写一个存储过程。 In it I have the following mysql insert statements:其中我有以下 mysql 插入语句:

INSERT INTO `Address`(`countryCode`, `addressLine1`, `addressLine2`, `postcode`, `region`, `city`) VALUES (country, addressLine1, addressLine2, postcode, region, city);
INSERT INTO `UserAddress`(`username`, `creationDate`, `addressId`) VALUES (username,NOW(),(SELECT addressId FROM Address ORDER BY addressId DESC LIMIT 1));

As you can see, I'm performing an insert on an Address table, and then use the auto incremented "addressId" in the subquery on the next line.如您所见,我正在对地址表执行插入操作,然后在下一行的子查询中使用自动递增的“addressId”。 Now, if between these 2 statements another transaction would insert something into the Address table I would insert the wrong addressId into the UserAddress table.现在,如果在这 2 个语句之间,另一个事务将向 Address 表中插入一些内容,我会将错误的 addressId 插入到 UserAddress 表中。 My guess would be I need to lock the Address table while these statements are being executed.我的猜测是我需要在执行这些语句时锁定地址表。

After a long search I found the following code to lock the Address table:经过长时间的搜索,我找到了以下代码来锁定地址表:

SELECT addressId FROM Address FOR UPDATE;

Would this also work for newly inserted rows?这也适用于新插入的行吗? If not, what would?如果不是,那会是什么?

Ideally, you should do it inside a Transaction , by using 'START TRANSACTION;'理想情况下,您应该在Transaction使用“START TRANSACTION;”进行操作and 'COMMIT' syntax.和“提交”语法。 You also need to set autocommit to 0 (it is enabled by default).您还需要将autocommit设置为 0(默认情况下启用)。 Here is the documentation for Transactions and autocommit.是交易和自动提交的文档。

As long as your updates are wrapped inside a transaction and appropriate isolation level is set, changes made by other transaction will not affect your transaction.只要您的更新包含在一个事务中并设置了适当的隔离级别,其他事务所做的更改就不会影响您的事务。

That's exactly why they invented a LAST_INSERT_ID这正是他们发明LAST_INSERT_ID 的原因

INSERT INTO `Address`(`countryCode`, `addressLine1`, `addressLine2`, `postcode`, `region`, `city`) VALUES (country, addressLine1, addressLine2, postcode, region, city);
INSERT INTO `UserAddress`(`username`, `creationDate`, `addressId`) VALUES (username,NOW(),LAST_INSERT_ID());

No need for locks or transactions or even stored procedures for the task of grabbing the last id.获取最后一个 id 的任务不需要锁或事务,甚至不需要存储过程。 Just do this in your app.只需在您的应用程序中执行此操作。

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

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