Php 拍卖出价-选择锁定共享模式是否会将信息保留在最新状态?
我目前正在研究如何在我的拍卖网站项目上管理大量的出价。由于很可能有些人会在完全相同的时间发送投标,很明显,我需要确保有锁来防止任何数据损坏 我已经开始使用Php 拍卖出价-选择锁定共享模式是否会将信息保留在最新状态?,php,mysql,sql,locking,innodb,Php,Mysql,Sql,Locking,Innodb,我目前正在研究如何在我的拍卖网站项目上管理大量的出价。由于很可能有些人会在完全相同的时间发送投标,很明显,我需要确保有锁来防止任何数据损坏 我已经开始使用选择共享模式下的锁定,该模式表示如果这些行中的任何一行被另一个尚未提交的事务更改,您的查询将等待该事务结束,然后使用最新的值。 这对我来说意味着投标将进入一个队列,在该队列中处理和检查每个投标,以确保投标高于当前投标,如果在该队列中插入后有变化,则使用最新的投标金额 然而,我已经读到,在两个用户试图同时出价的情况下,可能会出现破坏性的死锁问题
选择共享模式下的锁定
,该模式表示如果这些行中的任何一行被另一个尚未提交的事务更改,您的查询将等待该事务结束,然后使用最新的值。
这对我来说意味着投标将进入一个队列,在该队列中处理和检查每个投标,以确保投标高于当前投标,如果在该队列中插入后有变化,则使用最新的投标金额
然而,我已经读到,在两个用户试图同时出价的情况下,可能会出现破坏性的死锁问题,并且没有任何查询可以维护锁。因此,我也考虑过使用SELECT进行更新
,但这样也会禁用我不确定的任何读取
如果有人能对这个问题提出一些看法,我们将不胜感激,如果你能推荐任何其他数据库,比如NoSQL,它将更适合,那将是非常有帮助的
编辑:这本质上是一个并发问题,我不想用不正确/旧的数据检查当前出价,这将导致某些出价的“丢失更新”。就其本身而言,两次同时更新不会导致死锁,只是暂时阻塞。让我们叫他们Bid
A
和BidB
虽然我们认为它们是同时发生的,但我们会先获得一个锁。我们会说,A
更快到达那里1毫秒
A
获取有关行的锁B
将其锁请求放入队列,并且必须等待属于A
的锁释放。一旦锁A
被释放,B
就会获得它的锁
您的代码可能有更多内容,但从您的问题来看,正如我所描述的,不存在死锁场景。为了实现死锁,A
必须等待B
释放它对另一个资源的锁,但是B
在获得对A
的资源的锁之前不会释放它的锁
如果您需要实时验证投标,您可以:
A.使用适当的事务隔离级别(可能是可重复读取,这是InnoDB中的默认值),并在显式事务中执行选择和更新
BEGIN TRAN
SELECT ... FOR UPDATE
IF ...
UPDATE ...
COMMIT
在Update语句本身中执行检查逻辑。换句话说,构造更新查询,使其仅在当前出价小于新出价时影响行。如果没有记录受到影响,出价就太低了。这是一种可能的方法,可以减少数据库的工作量,但有其自身的考虑因素
UPDATE ...
WHERE currentBid < newBid
更新。。。
其中currentBid
就我个人而言,我的投票是选择A,因为我不知道你的逻辑有多复杂
可重复读取
隔离级别将确保每次读取事务中的给定记录时,该值都保证相同。它通过在行上保持一个锁来实现这一点,该锁阻止其他人更新给定行,直到您的事务提交或回滚为止。在最后一个连接完成其事务之前,一个连接无法更新表
底线是您的选择/更新将在数据库中是原子的,因此您不必担心更新丢失
关于并发性,关键是使事务尽可能短。进去,出去。默认情况下,无法读取正在更新的记录,因为它处于不确定状态。这些更新和读取只需几秒钟的时间 对于这样的应用程序,您希望
可序列化
,至少对于实际的“检查状态,提交投标”部分是这样的。@M\M谢谢!正是我需要的。只是需要澄清一下!有关InnoDB@DanielWest中隔离级别的详细信息,请参阅此问题的答案,以了解差异的详细解释:.ASELECT。。。对于更新
,默认的可重复读取
将为您提供与可序列化
事务相同的好处。