【发布时间】:2017-02-16 22:31:40
【问题描述】:
问题:
- 程序使用
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 的退化之一,此时我们甚至不需要池),就是以某种方式记住 @987654331 使用了池中的哪个特定连接@,并让runSQL2() 请求相同的连接。
com.mchange.v2.c3p0.ComboPooledDataSource 有没有办法做到这一点?
如果可能,我想要一个并发安全的答案(换句话说,如果 runSQL1() 中使用的连接被另一个线程使用,runSQL2() 的获取连接调用将等到该连接被另一个线程释放)。
但是,如果这是不可能的,我可以接受假设数据库连接(我关心的那些)都发生在一个线程中的答案,因此 runSQL2() 请求的任何连接都将 100% 可用如果它可用于 runSQL1()。
我也欢迎任何以其他方式解决问题的解决方案,只要它们不涉及“停止使用 #temptables”作为解决方案的一部分。
【问题讨论】:
-
为什么不能在运行 part1 之前请求连接,然后将其作为参数传递给两个调用?
-
@ivan 做到了。但我不喜欢这个解决方案,所以我想知道如何获得特定的连接
-
我也认为@Ivan 提出的解决方案是正确的解决方案。为了以任何其他方式获得它,您需要在第一次收到连接时至少保留一个标识符。完成后,您需要在池管理器上使用反射并找到匹配的连接。而不是仅仅持有对特定连接的引用更干净。如果您确实需要通过使用标识符进行查询来做到这一点,您可以编写自己的包装连接管理器并使用它。
-
你用你的
ComboPooledDataSource做什么?它应该在数据库使用期间保持打开状态。使用它从中获取您的连接对象。如果#temptable 依赖于特定的连接,那么您只能重复使用与执行runSQL1()相同的连接。另外,您是否尝试过创建可共享的临时表?
标签: java datasource connection-pooling