【问题标题】:Thread-safety of a simple & complex stored procedure in MySQLMySQL中简单和复杂存储过程的线程安全
【发布时间】:2016-01-28 08:51:54
【问题描述】:

出于这个问题的目的,我将 complex 存储过程定义为“一个涉及(至少)一个游标和(至少)一个循环以将数据插入临时表,然后从所述临时表中返回记录'。

在处理如此复杂的存储过程时,有人告诉我,当两个不同的用户登录到应用程序执行调用相同过程的操作时,因为过程很复杂,可能需要几秒钟(~10 秒) 来完成执行,那么每个用户的结果可能不忠实。也就是说,结果可能会混淆,当一个用户尝试访问 same 临时表时,他们可能会看到为其他用户准备的结果。

建议为每个用户使用系统生成的唯一标识符,以便区分每个用户的结果集。

现在,我想知道以下几点:-

  1. 是否可以通过使用任何表或数据库引擎配置设置来避免此并发问题?

  2. 这是否违反了一项或多项 ACID 属性?使用完全符合 ACID 的数据库引擎(例如我正在使用的 InnoDB)对这个问题有何影响?

  3. 简单存储过程的情况下,当执行时间几乎是总是不到一秒钟,并发仍然是个问题吗?

【问题讨论】:

  • 几乎总是一个游标可以被一条 SQL 语句替换。挑战自己首先。如果你不能,那么也许我们可以讨论实际代码。
  • @RickJames:感谢您的评论。我完全同意你的观点。看来我最初误解了这个问题。该问题似乎与使用所有“线程”通用的临时表有关。所以,我已经更新了这个问题,现在它纯粹是一个理论问题。看看你现在能不能回答。

标签: mysql stored-procedures concurrency innodb temp-tables


【解决方案1】:

好的,“光标”无关紧要。您只希望同一用户在多个连接中同时运行一个长时间运行的存储过程。

连接(别名会话)是“独立”的单位。实体(例如表)要么是特定于连接的,要么是全局的(除了权限问题)。没有什么“特定于用户”。

CREATE TEMPORARY TABLE 对于创建它的连接 是唯一的。 last_insert_id() 同上。这些是“线程安全的”,因为“连接”就是“线程”。

如果您想让多个连接(同一用户或不同用户)访问同一个“临时”表,那么您可以创建一个非TEMPORARY 表并以某种方式知道该表的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多