【发布时间】:2012-04-08 16:05:21
【问题描述】:
我听说许多应用程序开发人员在数据库处理中的竞争条件方面遇到了一些麻烦。一个典型的例子是这样的:
- 用户 1 选择一个字段,例如 numStock,即 3
- 用户 2 也选择了 numStock,仍然是 3
- 用户 1 递减 numStock(在应用程序中),并在数据库中将其设置为 2。
- 用户 2 还会减少 numStock(在应用程序中),并在数据库中将其设置为 2。
在本例中,numStock 字段本应为 1,但由于用户之间的竞争,它被设置为 2。
所以当然可以使用锁,但我想到了另一种处理方式 - 将所有行详细信息作为 WHERE 标准传递。让我解释一下……
在上面的示例中,SQL 代码可能如下所示:
//选择
SELECT itemID, numStock FROM items WHERE itemID = 45
//更新
UPDATE items SET numStock = 2 WHERE itemID = 45
我解决比赛的想法:
//选择
SELECT itemID, numStock FROM items WHERE itemID = 45
//更新
UPDATE items SET numStock = 2 WHERE itemID = 45 AND numStock = 3
因此,查询会检查数据在选择数据后是否发生了变化。 所以我的问题是: (1) 这[总是] 有效吗? (2) 与数据库锁定机制(例如 MySQL 事务)相比,这是一个更好的选择吗?
感谢您的宝贵时间。
【问题讨论】:
-
对于您的情况,您可以使用增量而不是将其设置为特定值。这样,如果两个单独的进程都想增加 numStock,它们将不会相互竞争。
SET numStock = numStock + 1
标签: database race-condition transaction-isolation