问题:
- 程序使用
com.mchange.v2.c3p0.ComboPooledDataSource
连接到 Sybase 服务器 - 程序依次执行
runSQL1()
和runSQL2()
两个方法 runSQL1()
执行创建#temptable 的 SQLSELECT * INTO #myTemp FROM TABLE1 WHERE X=2
runSQL2()
执行从这个 #temptable 中读取的 SQLSELECT * FROM #myTemp WHERE Y=3
问题:
runSQL2()
从池中获得了与传递给runSQL1 的不同的数据库连接()
。但是,Sybase #temptables 是特定于连接的,因此
runSQL2()
在找不到表时会失败。
我能想到的最明显的解决方案(除了使池大小为 1 的退化之一,此时我们甚至不需要池),是以某种方式记住池中的哪个特定连接被 runSQL1()
,并让 runSQL2()
请求相同的连接。
com.mchange.v2.c3p0.ComboPooledDataSource
有没有办法做到这一点?
如果可能,我想要一个并发安全的答案(换句话说,如果 runSQL1() 中使用的连接正在被另一个线程使用,runSQL2() 获取连接的调用将等到该连接被另一个线程释放)。
但是,如果那是不可能的,我同意假设数据库连接(我关心的那些)都发生在一个线程中的答案,因此 runSQL2() 请求的任何连接都将 100% 可用如果它可用于 runSQL1()。
我也欢迎任何以其他方式解决问题的解决方案,只要它们不涉及“停止使用#temptables”作为解决方案的一部分。
最佳答案
最简单和最明显的方法就是从池中请求连接,然后使用该连接运行 runSQL1()
和 runSQL2()
。问题中建议的使用模式违背了连接池管理器的一般设计原则,因为它会有效地将它们提升为某种事务管理器。
有些 Java 框架可能有助于上述操作。例如在 Spring 中,@Transaction
或 TransactionTemplate
可用于划分事务边界,它将保证单个连接由单个线程使用(或更准确地说,根据事务传播注释)。 Spring 可以使用许多事务管理器,但可能最简单的是使用 DataSourceTransactionManager它也可以配置为使用 c3p0
作为 DataSource
。
关于java - 如何从 com.mchange.v2.c3p0.ComboPooledDataSource 请求特定连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39925469/