为来自 MySQL InnoDB 存储过程的插入锁定 table
Locking a table for inserts from a MySQL InnoDB Stored Procedure
我正在写一个存储过程。其中我有以下 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));
如您所见,我正在对地址 table 执行插入,然后在下一行的子查询中使用自动递增的 "addressId"。现在,如果在这两个语句之间,另一个事务将向地址 table 中插入一些内容,我会将错误的地址 ID 插入到用户地址 table 中。我的猜测是我需要在执行这些语句时锁定地址 table。
经过长时间的搜索,我找到了以下代码来锁定地址table:
SELECT addressId FROM Address FOR UPDATE;
这也适用于新插入的行吗?如果不是,那会是什么?
理想情况下,您应该使用 'START TRANSACTION;' 和 'COMMIT' 语法在 Transaction
中执行此操作。您还需要将 autocommit
设置为 0(默认情况下启用)。 Here 是事务和自动提交的文档。
只要您的更新包含在事务中并且设置了适当的 isolation level,其他事务所做的更改就不会影响您的事务。
这正是他们发明 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());
不需要锁或事务,甚至不需要存储过程来完成获取最后一个 ID 的任务。只需在您的应用中执行此操作即可。
我正在写一个存储过程。其中我有以下 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));
如您所见,我正在对地址 table 执行插入,然后在下一行的子查询中使用自动递增的 "addressId"。现在,如果在这两个语句之间,另一个事务将向地址 table 中插入一些内容,我会将错误的地址 ID 插入到用户地址 table 中。我的猜测是我需要在执行这些语句时锁定地址 table。
经过长时间的搜索,我找到了以下代码来锁定地址table:
SELECT addressId FROM Address FOR UPDATE;
这也适用于新插入的行吗?如果不是,那会是什么?
理想情况下,您应该使用 'START TRANSACTION;' 和 'COMMIT' 语法在 Transaction
中执行此操作。您还需要将 autocommit
设置为 0(默认情况下启用)。 Here 是事务和自动提交的文档。
只要您的更新包含在事务中并且设置了适当的 isolation level,其他事务所做的更改就不会影响您的事务。
这正是他们发明 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());
不需要锁或事务,甚至不需要存储过程来完成获取最后一个 ID 的任务。只需在您的应用中执行此操作即可。