mysql - 如何使用 SELECT FOR UPDATE

标签 mysql sql

我正在使用 MySQL 5.0

我的应用程序由多个用户使用。所有数据都由一个共享表products(用于更新)提供,我不想丢失任何用户更新,我不能锁定整个表,因为它会减慢我的应用程序。出于同样的原因,我无法在我的程序中应用锁定。

现在我想使用:

SELECT * FROM products limit 1;

...以便其他数据库连接在更新完成之前无法读取此行。

我试过:

query = "select  min(nextag_product_id) from products where is_bottomline = 0 and timestamp <= date_sub(now(),  interval 30 minute) for update"

...但这无法锁定其他连接以读取此行。同一时间同一产品对多个用户开放。

对于 MySql,执行 SELECT FOR UPDATE 的正确提示是什么?

最佳答案

您可以使用提示 with(xlock) 来锁定行,这将设置独占锁。在这种情况下,在第一个事务提交或回滚之前,其他事务甚至无法读取锁定的数据。

如果您希望其他事务能够读取第一个事务未选择的数据,您需要在两个事务中使用Index Seek 来实现读取数据。
假设我们要进行交易:

/* 1st transaction */
SELECT *
FROM tbl with(xlock)
WHERE field1=1

/* 2nd concurrent transaction */
SELECT *
FROM tbl with(xlock)
WHERE field1=2
/* 3d concurrent transaction */
SELECT *
FROM tbl
WHERE field1=1

如果您在 1field11 上没有索引,那么第二个事务将不得不等待第一个事务完成。
但是,如果您在 field1 上创建索引,则第二个事务将并行执行,而第三个事务仍将等待第一个事务的结束。

CREATE INDEX IX_tbl_field1 ON tbl

关于mysql - 如何使用 SELECT FOR UPDATE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24668926/

相关文章:

php - 仅使用 PHP 的虚拟页面?

php - MySQLi 多查询不起作用

java - Hibernate - 对具有枚举属性的 Bean 使用 native 查询和别名?

sql - 我如何使用 CASE-WHEN 将空值列设置为 0?

java - MySQL - 对象不为空?

mysql - MySQL 表的 INSERT 语句

php - 是否可以获得cpanel mysql数据库前缀?

mysql - 需要计算马的年龄

sql - 使用 TSQL 确定表的主键

sql - 如何在sql中引用一对属性?