MySQL Connector/JDBC 是否线程安全?

16

MySQL JDBC驱动程序是否线程安全?具体来说,我想在所有线程中使用单个连接,但每个语句只会在单个线程中使用。是否存在某些安全的方案和其他不安全的方案?你在这方面有什么经验?


3
“虽然您可以在不同的线程之间共享连接(特别是如果每个线程都有自己的Statement),但这通常不是一个好主意。 JDBC API实际上并没有被设计成以线程安全的方式使用,而且大多数JDBC连接(包括MySQL的)一次只能处理一个查询。” - Tim
1
@Tim,是的,我之前看到了这篇帖子。但它并没有详细说明可能存在的问题,所以我认为听听其他人的经验会很有趣。此外,我觉得这是一个合理的问题,适合放在Stack Overflow的问题数据库中。请随意将该链接作为答案发布。 :) - Emil H
1
考虑改用连接池。 - Dana the Sane
3个回答

11

事务是按照连接启动/提交的。除非您正在进行一些非常特殊的操作(说实话,我想不出有什么情况需要这样做),否则最好使用连接池和每个线程一个连接。


1
我在想是否有可能存在这样的用例,您想要执行某种分叉/汇聚算法(参见http://www.ibm.com/developerworks/java/library/j-jtp11137.html),但完全在一个事务中进行,因此您可以在起始线程中打开连接并启动事务,将其传递给所有任务执行器,然后在所有汇聚完成之后在起始线程中提交? - Graham Lea
使用load data local infile进行流式数据插入,插入到多个表中,其中数据具有相互关系,不能便宜地迭代两次。 - Barry Kelly

4
如果autocommit = 1,则非常可行让多个线程共享同一连接,只要对连接的访问进行同步。如果autocommit = 0,则必须通过某种互斥变量来控制连接的访问,直到提交发生为止。
除非您的应用程序绝对受限于连接数量,否则连接池可能是一个更可行的选择。

1
根据我的最近经验,Connector/J 5.1.33中的Connection对象不是线程安全的。
我遇到了一个死锁情况,详细请参见bug 67760。不确定这是否是一个错误,但讨论中一个合理的建议是:

[2012年12月12日20:33] Todd Farmer

请勿在没有适当同步的情况下跨多个线程使用单个Connection对象。 Connector/J - 更重要的是,MySQL客户端-服务器协议 - 不允许使用相同的Connection对象进行并发操作。 如果必须跨线程共享Connection对象,则应用程序代码作者有责任确保操作被正确序列化。


FYI,那个 bug 现在应该在 5.1.37 中已经修复了。 - Archie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接