我听说很多应用程序开发人员在数据库处理的竞争条件方面遇到了一些麻烦。一个典型的例子是这样的:
在这个例子中,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事务)相比,这是一个更好的选择吗?
感谢您的时间。
答案 0 :(得分:5)
此策略有效,称为“乐观锁定”。那是因为你做了你的处理,假设它会成功,并且只在最后实际检查它是否成功。
当然,您需要一种方法来重试交易。如果失败的可能性非常高,可能会变得低效。但在大多数情况下,它的工作正常。
答案 1 :(得分:0)
如何在单个语句中进行选择和更新:
UPDATE counters SET value = (@cur_value := value) + 1 WHERE name_counter = 'XXX';
然后
SELECT @cur_value;
此策略可以解决竞赛条件吗?