MySQL:如何确保更新始终在选择之前执行?

标签 mysql sql

我正在创建一个网络应用程序,允许 N 个用户输入收据数据。

向用户提供一组扫描收据,但处理同一张收据的用户不得超过 2 个。

即用户A和用户B可以处理收据-1,但用户C不能处理它(另一个收据,比如收据-2,应该分配给用户C)。

我使用的表结构类似于以下内容。

[用户收据表]

+------------+--------------+
|  user_id   |  receipt_id  |
+------------+--------------+
| 000000001  |  R0000000000 |
| 000000001  |  R0000000001 |
| 000000001  |  R0000000002 |
| 000000002  |  R0000000000 |
| 000000002  |  R0000000001 |
+------------+--------------+

[收据表]

+-------------+--------+
| receipt_id  | status |
+-------------+--------+
| R0000000000 |    0   |
| R0000000001 |    1   |
| R0000000002 |    0   |
| R0000000003 |    2   |
+-------------+--------+

★状态 0:未分配 1:分配给一个用户 2:分配给 2 个用户

  1. 从收据表中选择状态不等于“2”的收据
  2. 插入从第 1 步获取的收据以及分配了收据的用户。
  3. 更新收货状态(0->1 或 1->2)

这就是我计划实现上述要求的方式。

这种方法的问题在于,select(step1)有可能在update(step3)执行之前执行。 如果发生这种情况,状态为 2 的收据可能会被获取并分配给其他用户,这不符合要求。

如何确保这种情况不会发生?

最佳答案

出于所有目的,请使用 transactions :

START TRANSACTION
   your SQL commands
COMMIT

事务要么让所有语句执行,要么根本不执行,并在更新的行上隐式执行锁定,这比第二种方法更有效

您还可以使用 LOCK TABLE 来完成此操作

关于MySQL:如何确保更新始终在选择之前执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47958506/

相关文章:

sql - 我应该在数据库连接字符串中设置最大池大小吗?如果我不这样做会怎样?

sql - Hypertable 与 HBase 以及 BigTable 与 SQL

sql - 为什么 SQL Server 在按主键分组时需要聚合函数?

mysql - 最小距离和分组依据

sql - 如何根据值限制返回的列?

mysql - 如何添加不同行的数据并将它们显示为sql查询中一行的列

sql - 更新SQL Server表中所有行的更快方法

mysql - 插入 ID 号而不是使用 Enum 类型 - 查询会变慢多少?

php - 如何使用查询 CI 语法编写 SQL 查询?

Java/SQL : return an average from a specific column problem