PHP和并发

Zac*_*ght 7 php database concurrency

我最近在PHP上做了一些Web开发工作,这使我一直在学习语言.到目前为止,我不需要使用它来与数据库进行交互,但我知道它提供了许多方便的功能.

虽然我知道基本的SQL并且已经在数据库中使用数据的基本操作,但我不明白基于PHP/Javascript/SQL建立网站的Web开发人员能够管理同时修改相同数据的用户.

例如,假设您有一个二十一点网站,用户在注册时将用户划分为两个团队中的一个.每当用户赢得游戏时,他们的部分奖金将被添加到该团队的运行总计中.

那么让我们说这个函数的伪代码看起来像这样:

... 
$total = mysql_query("SELECT score FROM team1");
$total = $total + $mytotal;
mysql_query("UPDATE team1 SET score='".$total."'");
...
Run Code Online (Sandbox Code Playgroud)

如果两个玩家同时玩,那么他们很有可能在另一个玩家有机会增加和更新表之前调用SELECT,因此一个用户的更改将立即被覆盖.

我的问题是,如何避免这种情况?它是在代码级使用PHP完成的,还是由您使用的任何数据库提供的功能有助于防止这种情况?

我一直在做一些研究,似乎PHP确实提供了信号量机制,我也注意到mysql提供了一个LOCK表功能.但是,我不确定在实践中使用哪一种,如果有的话.

Jé *_*eue 11

保持DB的逻辑,这些语义大多已经为你解决了.

update teams
set score = score + 1
where team_id = 1
Run Code Online (Sandbox Code Playgroud)

..或任何得分和任何球队号码.


Byr*_*ock 5

如果你的真实世界问题比这个简单的例子大,你应该将一个事务与锁表结合使用,以确保用户不会相互覆盖.


Nir*_*mal 5

主要数据库都是为了处理这种情况而设计的。

使用 MySQL 时,InnoDB 存储引擎具有行锁定功能,该功能会锁定正在写入的行。因此,针对同一行的任何更新请求都将等待,直到该行的上一个操作完成。

如果您使用 MyISAM 存储引擎,则在更新行时会锁定整个表。当多个玩家同时推送更新请求时,这会导致服务器阻塞。因此,这完全取决于您为此目的使用什么数据库,特别是什么存储引擎。