如何在mysql中管理并发?

时间:2016-07-19 04:14:05

标签: php mysql concurrency

我坚持这个。为了简化,让我说我有这个表

CREATE TABLE IF NOT EXISTS `tbl_bags_oranges` (
  `idbag` int(11) NOT NULL AUTO_INCREMENT,
  `n_oranges` int(11) NOT NULL,
  PRIMARY KEY (`idbag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=1 ;

我正在开发一个PHP脚本,代表用户抓橙子的情况。这就是我正在做的事情:

  1. 我使用SELECT检查给定idgab中是否有橙子(n_oranges> 0)
  2. 如果是这样,我UPDATE表格减去1到n_oranges
  3. 但如果袋子里只有一个橙子,可能会发生以下情况:

    1. 用户A想抓橙色。 'SELECT'说有一个橙色。
    2. 用户B想抓橙色。 'SELECT'说有一个橙色。
    3. 用户A抓住橙色。我UPDATE表,现在n_oranges = 0。
    4. 用户B能够抓住橙色,因为他的SELECT表示有一个橙色。
    5. 我该如何解决这个问题?交易? LOCK TABLES?由于我无法检查这种情况,因此无法知道我做得好不对。

2 个答案:

答案 0 :(得分:0)

您可以在更新表格时进行检查:

UPDATE `tbl_bags_oranges`
SET n_oranges=n_oranges-1 
WHERE n_oranges>=1;

您可以根据自己的情况修改代码。

答案 1 :(得分:0)

您可以使用locking reads。 详细说明:

  • 确保autocommit已停用
  • START TRANSACTION
  • SELECT ... FROM tbl_bags_oranges WHERE ... FOR UPDATE
  • 在您的代码中执行您需要执行的任何操作
  • 保存新值UPDATE tbl_bags_oranges SET ...
  • COMMIT

在这种情况下,在您的方案中,第二个查询将阻塞,直到第一个事务提交,因此不会发生竞争条件