【问题标题】:concurrent access to MySQL database using stored procedure使用存储过程并发访问 MySQL 数据库
【发布时间】:2011-09-22 19:58:58
【问题描述】:

我有一个存储过程,它将读取数据库中的一个值,然后增加一个值。许多程序同时使用此特定过程。我担心并发问题,尤其是读写器问题。有人可以建议我任何可能的解决方案吗?

谢谢。

【问题讨论】:

  • 您可能应该在存储过程中使用事务......也许我是老式的并且有一些更现代的方法,但我使用事务来实现这一点 - 我对每个可以使用的操作都使用事务'不要写成单个查询。
  • 但事务不会阻止另一个应用程序读取该值...我的意思是如果进程 A 正在使用存储过程 [使用事务] 更新 row1 的 column1,那么进程 B 仍然可以读取row1 的 column1,但它将获取现有值而不是更新值。希望你明白我的意思。如果我错了,你能解释一下吗?
  • 使用事务你不会拒绝进程 B 完成他的工作,而这根本不是事务的目的。事务的目的是始终获得一致的状态,就好像进程是唯一同时使用数据库的进程。因此,当进程 A 处于事务中间时,进程 B 可以读取数据库的旧状态。而且每笔交易都会像没有其他人同时使用数据库一样通过。
  • 正确,这就是我的问题......事务不会阻止其他进程访问相同的值......它只会确保读取和写入操作不会同时发生拒绝访问....但是一旦我开始更新它,我需要锁定该行。但据我所知,存储过程中不允许使用 LOCK ......如果我错了,请纠正我。

标签: mysql stored-procedures concurrency


【解决方案1】:

首先,如另一篇文章所述,使用 InnoDB。它是 MySQL 5.5 的默认存储引擎,并且更加健壮。

二、看这个页面:http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html

您应该使用 SELECT ... FOR UPDATE 来防止其他连接读取您将要更新的行,直到您的事务完成:

START TRANSACTION;

SELECT value INTO @value
FROM mytable
WHERE id = 5
FOR UPDATE;

UPDATE mytable
SET value = value + 1
WHERE id = 5;

COMMIT;

这比锁定表要好,因为 InnoDB 会进行行级锁定。上面的事务只会锁定 id = 5 的行...所以另一个使用 id = 10 的查询不会被这个查询阻塞。

【讨论】:

    【解决方案2】:

    如果可能,您可以在调用 SP 之前锁定表,然后立即解锁。 我有类似的问题,这就是我绕过这个问题的方法。

    例子

    LOCK TABLES my_table LOW_PRIORITY WRITE;
    CALL my_stored_procedure('ff');
    UNLOCK TABLES;
    

    【讨论】:

    • 如果任何其他过程试图使用被锁定的表会发生什么?它会等到锁被释放还是会导致异常?
    • @Akshay 它将等待表被解锁
    【解决方案3】:

    使用 Innodb。 在执行任何其他操作之前,在存储过程中启动事务。在提交并结束事务。这将解决读/写问题。

    但请注意,它会减慢并发操作。对于在给定时间仅预期少数并发请求的情况是可以的。

    【讨论】:

    • 您能否解释一下交易将如何解决我的问题....请阅读我对“Tomas T.”的评论上面的回应。
    • 好的。在这种情况下,您必须使用 LOCK TABLE。即,您必须明确锁定表不被读取。并在您的工作完成后释放锁定。但它也有自己的陷阱dev.mysql.com/doc/refman/5.0/en/lock-tables.html
    • 是的,但我不能在存储过程中使用 LOCK,可以吗?
    • 好的,你是对的。你能发布存储过程代码吗?我会考虑是否有其他选择。
    • 您可以在调用过程之前在php代码中锁定表。程序刚刚完成解锁表后。即 mysql_query("LOCK TABLES tablename READ;"); mysqli_query("调用存储过程"); mysql_query("解锁表;");
    【解决方案4】:

    为所有增量插入创建一个单独的表(或在适当的情况下重复使用原始表)并使用 SUM() 进行检索。

    如果仍然担心最终行的数量,请使用事务将它们定期汇总到原始表中的单行中。与等待锁定单行的多个写入器的停顿相比,总和的最终一致性(读取滞后于写入)或求和行的性能损失很可能不是问题。

    【讨论】:

      猜你喜欢
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多