【问题标题】:How to solve c3p0 concurrency issues?如何解决c3p0并发问题?
【发布时间】:2018-02-23 19:36:17
【问题描述】:

我正在尝试实现数据库连接池。出于某种原因,我在使用多个线程时会随机出现异常。

当我只有一个时,一切都很好。此外,至少在我进行测试时,问题只出现在开始时。由于我不确定是什么原因造成的,因此我不能确定它们以后不会发生。

使用 c3p0 版本 0.9.5.2

Example output from my test: https://pastebin.com/NrcR6mhz

这个测试有 3 个线程,每个线程运行 1000 次简单查询。我把输出缩短了,因为后面没有例外。

tl;dr 版本的错误消息:

  • 不能对已关闭的 Statement 进行操作!!!
  • 不能对关闭的连接进行操作!!!

我不会费心上传整个项目,因为 DB 是单独配置的。不过,你可以在这里看到我所有类的代码:

Main - https://pastebin.com/1Rgjr8H5

Pool conf https://pastebin.com/wtbw1X5v

Controller https://pastebin.com/BvPh0guY

由于 c3p0 似乎不错的库恕我直言,我想我在这里做错了什么。请问有什么建议吗?

【问题讨论】:

标签: java mariadb c3p0


【解决方案1】:

因此,您需要考虑一下多线程编码的工作原理,为什么人们通常应该更喜欢只能在本地范围内访问的对象而不是实例或静态成员变量,以及何时应该同步以安全访问必须在之间共享的对象线程。

您最基本的问题是 MariaController.connection 是一个静态成员变量,而它应该完全是 isPlayerSuspended(...) 的本地变量。

你还应该标记静态MariaConnectionPool.getInstance()方法synchronized[相当于用synchronized( MariaConnectionPool.class ){ ... }包围鳕鱼的身体]。

可能还有其他问题。编写多线程代码需要您仔细考虑可以共享的内容和时间,并且通常的答案是通过在只能通过方法内的本地引用访问的对象中使用可变状态来避免共享可变状态(对其的访问本质上是单线程的)。

【讨论】:

  • 感谢您的提示。多线程对我来说是新事物,我经常会忘记最简单的事情。问题解决了。
猜你喜欢
  • 1970-01-01
  • 2018-02-08
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 2010-10-11
相关资源
最近更新 更多