【问题标题】:can more than one thread operate the same database?多个线程可以操作同一个数据库吗?
【发布时间】:2013-04-07 11:07:20
【问题描述】:

我无法理解的场景:

一个名为 DBserver 的进程有五个线程,每个线程都有一个与 Mysql 数据库的连接。每次我们要执行一条sql,我们将它发送给DBserver,然后DBserver会选择一个线程来执行。现在来了两个sql,分别称为sqlA和sqlB,sqlA在sqlB之前, 但由于DBserver使用多线程,不能保证sqlA先于sqlB执行。 如果 sqlB 真的在 sqlA 之前执行,我认为会发生错误。

例如:

sqlA:update bankTable set money = 10 where id = 10001;

sqlB:update bankTable set money = 100 where id = 10001;

如果sqlB在sqlA之前执行,最后的钱是10,应该是100。 但是这个DBserver已经上线了,没有出现任何错误,我不知道为什么。非常感谢!

【问题讨论】:

  • 数据库服务器抛出错误的任何原因?任何方式 last update 语句都会更新数据
  • 乍一看,这看起来不像是关于 MySQL 的问题,也不是关于您正在使用的任何数据库驱动程序/库的问题。很明显,这一行的货币价值应该是 10 或 100,并且任何排序要求都必须在您的 (pthreads) 代码中实现。如果您在现有的“金钱”余额中添加 10 和 100,那么这可能与 ACID 合规性(对于依赖于存储引擎的 MySQL)和您选择的连接库的线程安全有关。
  • @tonyli 你的问题得到解答了吗?

标签: mysql database pthreads threadpool


【解决方案1】:

为什么会发生错误?你的意思是说,这不是你期望发生的。就这样。但是这两个查询都可以按任意顺序执行,不会出错。

对于这个例子,我假设 sqlA 总是在 sqlB 之前执行,因为两个查询中的工作是相同的,主线程会将查询传递给空闲线程。

但如果我们讨论的是更复杂的查询:我想这就是表锁定发挥作用的地方。

【讨论】:

  • 是的,你是对的,这两个查询都可以按任意顺序执行,不会出错。但从逻辑上讲,钱变少了。也许就像 Jim Dennis 所说,使用交易可以解决这个问题。
  • @TonyLi 我不认为交易对你有帮助,当从 2 个不同的脚本/请求工作时,因此 2 个不同的交易。但是您需要做的不是set money = 10,而是set money = money + 10set money = money - 90。这样它就可以继续工作,而不必担心哪个查询先进行
【解决方案2】:

看来您想要的是在仍然抽象单个 SQL 查询的同时保留 ACID 合规性。

我的建议是构建一个接受 SQL 查询的类,以接受单个 SQL 查询(如字符串)或 SQL 查询列表。该列表意味着查询是相互依赖的,需要在同一个数据库连接上运行。

这在处理临时表时尤其重要,因为它们的范围仅限于数据库连接,并且对其他连接不可见。

【讨论】:

  • 是的,只用一个连接或只用一个线程都可以解决这个问题。谢谢。
  • @TonyLi 但这会影响你的表现。甚至可能大幅
  • 正如@nl-x 对其他回复的评论,交易可能对您没有帮助。并且减少到 1 个线程会严重影响性能。我的建议是聚合作为一个单元的所有语句,仅当它们以正确的顺序运行时才会生成特定的输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 2023-03-27
  • 1970-01-01
  • 2015-03-24
  • 2020-07-06
  • 2012-01-26
相关资源
最近更新 更多