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