Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 拍卖出价-选择锁定共享模式是否会将信息保留在最新状态?_Php_Mysql_Sql_Locking_Innodb - Fatal编程技术网

Php 拍卖出价-选择锁定共享模式是否会将信息保留在最新状态?

Php 拍卖出价-选择锁定共享模式是否会将信息保留在最新状态?,php,mysql,sql,locking,innodb,Php,Mysql,Sql,Locking,Innodb,我目前正在研究如何在我的拍卖网站项目上管理大量的出价。由于很可能有些人会在完全相同的时间发送投标,很明显,我需要确保有锁来防止任何数据损坏 我已经开始使用选择共享模式下的锁定,该模式表示如果这些行中的任何一行被另一个尚未提交的事务更改,您的查询将等待该事务结束,然后使用最新的值。 这对我来说意味着投标将进入一个队列,在该队列中处理和检查每个投标,以确保投标高于当前投标,如果在该队列中插入后有变化,则使用最新的投标金额 然而,我已经读到,在两个用户试图同时出价的情况下,可能会出现破坏性的死锁问题

我目前正在研究如何在我的拍卖网站项目上管理大量的出价。由于很可能有些人会在完全相同的时间发送投标,很明显,我需要确保有锁来防止任何数据损坏

我已经开始使用
选择共享模式下的锁定
,该模式表示
如果这些行中的任何一行被另一个尚未提交的事务更改,您的查询将等待该事务结束,然后使用最新的值。

这对我来说意味着投标将进入一个队列,在该队列中处理和检查每个投标,以确保投标高于当前投标,如果在该队列中插入后有变化,则使用最新的投标金额

然而,我已经读到,在两个用户试图同时出价的情况下,可能会出现破坏性的死锁问题,并且没有任何查询可以维护锁。因此,我也考虑过使用
SELECT进行更新
,但这样也会禁用我不确定的任何读取

如果有人能对这个问题提出一些看法,我们将不胜感激,如果你能推荐任何其他数据库,比如NoSQL,它将更适合,那将是非常有帮助的


编辑:这本质上是一个并发问题,我不想用不正确/旧的数据检查当前出价,这将导致某些出价的“丢失更新”。

就其本身而言,两次同时更新不会导致死锁,只是暂时阻塞。让我们叫他们Bid
A
和Bid
B

虽然我们认为它们是同时发生的,但我们会先获得一个锁。我们会说,
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中隔离级别的详细信息,请参阅此问题的答案,以了解差异的详细解释:.A
SELECT。。。对于更新
,默认的
可重复读取
将为您提供与
可序列化
事务相同的好处。