如何从com.mchange.v2.c3p0.ComboPooledDataSource请求特定连接?

时间:2016-10-07 20:39:56

标签: java datasource connection-pooling

问题:

  • 程序使用com.mchange.v2.c3p0.ComboPooledDataSource连接到Sybase服务器
  • 程序按顺序执行2个方法runSQL1()runSQL2()
  • runSQL1()执行创建#temptable

    的SQL
    SELECT * INTO #myTemp FROM TABLE1 WHERE X=2
    
  • runSQL2()执行从此#temptable

    读取的SQL
    SELECT * FROM #myTemp WHERE Y=3
    
  • 问题 runSQL2()从池中获取的数据库连接与传递给runSQL1()的数据库不同。

    但是,Sybase #temptables是特定于连接的,因此当 runSQL2()找不到表时会失败。

我能想到的最明显的解决方案(除了使池大小为1的退化之外,此时我们甚至不需要池),是以某种方式记住来自池的哪个特定连接被{{ 1}},并runSQL1()请求相同的连接

有没有办法在runSQL2()

中执行此操作

如果可能的话,我想要一个并发安全的答案(换句话说,如果另一个线程正在使用runSQL1()中使用的连接,runSQL2()调用get连接将等到该连接由另一个线程发布。)

然而,如果这是不可能的,我可以回答假定数据库连接(我关心的那些)都发生在一个单独的线程中,因此runSQL2()请求的任何连接都是100%可用的如果它可用于运行SQL1()。

我也欢迎任何以其他方式解决问题的解决方案,只要它们不涉及“停止使用#temptables”作为解决方案的一部分。

1 个答案:

答案 0 :(得分:0)

最简单,最明显的方法是从池中请求连接,然后使用该连接运行runSQL1()runSQL2()。问题中建议的使用模式违反了连接池管理器的一般设计原则,因为它会有效地将它们提升到某种事务管理器。

有些Java框架可能有助于上述内容。例如,在Spring @TransactionTransactionTemplate中可以用来划分事务边界,它将保证单个线程使用单个连接(或者更准确地说,根据事务传播注释)。 Spring可以使用许多事务管理器,但最简单的方法是使用DataSourceTransactionManager,也可以将c3p0配置为DataSource