【问题标题】:MySQL configuration for multiple-threading transactions多线程事务的 MySQL 配置
【发布时间】:2012-04-12 12:20:02
【问题描述】:

我有 6 个脚本/任务。他们每个人都启动一个 MySQL 事务,然后执行它的工作,这意味着从 MySQL 数据库中选择/更新/插入/删除,然后回滚。

所以如果数据库处于给定状态 S,我启动一个任务,当任务终止时,数据库又回到状态 S。

当我按顺序启动脚本时,一切正常:

  • 数据库处于 S 状态
  • 任务 1
  • 数据库处于 S 状态
  • 任务 2
  • 数据库处于 S 状态
  • ...
  • ...
  • 任务 6
  • 数据库处于 S 状态

但我想通过多线程和并行启动脚本来加快进程。

  • 数据库处于 S 状态
  • 同时完成 6 个任务
  • 数据库处于 S 状态

一些任务随机失败,我有时会收到这个错误:

SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction

我不明白,我以为交易就是为此而生的。有什么我想念的吗?欢迎任何经验、建议、线索。

MySQL的配置是:

innodb_lock_wait_timeout = 500
transaction-isolation = SERIALIZABLE

我在每个会话开始时添加 AUTOCOMMIT = 0。

PS:数据库是在我后来更改的 REPEATABLE READ 隔离级别下构建和使用的。

【问题讨论】:

  • 一些代码会有很长的路要走。听起来您遇到了变量同步问题。这可能是由于事务处于回滚状态等。
  • 很抱歉澄清我之前的评论,听起来您在变量/数据库状态处于未提交/回滚状态时遇到问题。
  • 好吧,在阅读了一些相关帖子之后,似乎这不是正确的做法。我需要为每个线程提供完全隔离的数据,所以我的见解是可能使用 6 个镜像数据库。
  • 看来您正面临查询执行时间的问题。为什么不看看查询是否可以优化。您确定它们运行有效吗?虽然有 6 个不同的数据库可以工作,但还有 6 个数据库需要照顾。您是否对正在使用的所有查询都运行了 EXPLAIN ALL?你确定不能让它们跑得更快吗?

标签: mysql multithreading transactions deadlock isolation-level


【解决方案1】:

您可以通过确保每个事务/进程对所有必需的数据/表执行 SELECT...FOR UPDATE 来防止死锁,在所有情况下使用相同的 ORDER BY 并且表本身的顺序相同(至少可重复MySQL 中的读取隔离级别)。

除此之外,隔离级别和事务不是用来处理死锁的,反之亦然,它们是死锁存在的原因。如果您遇到死锁,很有可能您的数据集状态会不一致(这可能会更严重 - 如果不是,您可能根本不需要事务)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-10
    • 2023-03-04
    • 2011-01-07
    • 2016-10-17
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多