【问题标题】:MySQL: Transactions across multiple threadsMySQL:跨多个线程的事务
【发布时间】:2010-03-22 20:49:58
【问题描述】:

初步:

我有一个应用程序,它维护一个包含大约 100 个线程的线程池。在新任务替换它之前,每个线程可以持续大约 1-30 秒。当一个线程结束时,该线程几乎总是会在一个表中插入 1-3 条记录,该表被所有线程使用。现在,不存在事务支持,但我现在正在尝试添加它。此外,有问题的表是 InnoDB。所以...

目标

我想为此实现一个事务。此事务是否提交或回滚的规则驻留在主线程中。基本上有一个简单的函数会返回一个布尔值。

  1. 我可以跨多个连接实现事务吗?
  2. 如果不能,多个线程可以共享同一个连接吗? (注意:这里有很多插入,这是一个要求)。

【问题讨论】:

    标签: mysql multithreading transactions


    【解决方案1】:

    1) 不可以,事务仅限于单个数据库连接。

    2) 是的,一个连接(和事务)可以在多个线程之间共享。

    【讨论】:

    • 至于(2),如果表是INNODB,我认为同时发生多个插入是安全的吗?
    • @Zombies 是的,虽然我没有使用 InnoDB 和 Transactions 的经验,但我相信应该没问题。我认为它没有理由不工作。
    【解决方案2】:

    好吧,正如另一个答案中所述,您不能跨多个连接创建事务。您可以跨线程共享单个连接。 但是你需要非常小心。您需要确保只有一个线程同时写入连接。您不能只让多个线程通过同一连接进行通信,而不以某种方式同步它们的活动。如果您允许两个线程同时交谈(客户端库中的内存损坏等),则可能会发生不好的事情。使用互斥体或临界区来保护连接对话可能是可行的方法。

    -唐

    【讨论】:

    • 也许,我想我可以通过让线程在提交之前等待主线程的测试完成来重新考虑这一点。
    • 只是一个想法,没有测试:如果你自己创建start_transaction()和commit()/rollback()函数,并且你在start_transaction()中锁定一个互斥锁并在事务结束时解锁它,事务在线程中使用会更安全。我并不是说它会像来自不同的连接一样工作。只是有时你在线程中启动事务并且你依赖它们是原子的。另请注意,mysql 认为一次只能在所有线程中运行一个查询。这包括从查询运行到完成获取结果。
    • 连接上的通信需要序列化。一种方法是有一个专用的通信线程,让其他线程做任何必要的工作,然后将结果传递给通信线程,由它序列化语句。
    【解决方案3】:

    在很多线程之间共享连接通常是通过使用连接池来实现的。每个线程都可以从池中请求连接,将其用于其目的(一个或多个事务,提交或回滚),并在任务完成后将其交回池。

    这就是应用服务器为您提供的。他们也会处理交易,我。 e.当请求事务的方法正常完成时,提交更改,如果抛出异常,则回滚数据库事务。

    我建议您看看 Java EE 5 或 6 - 它非常易于使用,甚至可以在嵌入式系统中使用。为了便于开始,请查看 Netbeans 和 Glassfish 应用程序服务器。但是,一般概念同样适用于所有应用程序服务器。

    对于 InnoDB,它处理大量事务不会有任何问题。在应用服务器的监督下,您可以专注于业务逻辑,而不必担心写一半的更新或任何人在它们源自的事务提交之前看到更新/插入。

    InnoDB 使用 MVCC(多版本并发控制),有效地为每个事务提供自启动时整个数据库的快照。您可以在相关问题中阅读有关 MVCC 的更多信息:Question 812512

    【讨论】:

    • 这不会部署在 J2EE 上。但它会在未来使用 J2SE 连接池是的。所以我认为我可以回滚连接池中的所有连接......?
    • 是的,MVCC 默认的事务隔离级别为“可重复读”,这意味着一旦一个事务读取了第一位数据,它就不会看到来自其他事务的任何更新,即使这些是坚定的。只有当当前事务提交或回滚时,此连接上的下一个事务才会看到提交到该点的其他所有人的新数据。
    • 要明确一点:您将无法发出单个“回滚所有打开的事务”命令。但这通常不是你想要的——如果是这样,我认为你需要对你的系统有更多的了解,因为它看起来不对。
    • 我实际上对回滚不感兴趣,如果主线程中的测试失败,这更像是一种不提交错误数据的故障保护。什么是“MVCC”?
    • 请看我回答的最后一段和里面的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多