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

标签 java datasource connection-pooling

问题:

  • 程序使用 com.mchange.v2.c3p0.ComboPooledDataSource 连接到 Sybase 服务器
  • 程序依次执行 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 的退化之一,此时我们甚至不需要池),是以某种方式记住池中的哪个特定连接被 runSQL1(),并让 runSQL2() 请求相同的连接

com.mchange.v2.c3p0.ComboPooledDataSource 有没有办法做到这一点?

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

但是,如果那是不可能的,我同意假设数据库连接(我关心的那些)都发生在一个线程中的答案,因此 runSQL2() 请求的任何连接都将 100% 可用如果它可用于 runSQL1()。

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

最佳答案

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

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

关于java - 如何从 com.mchange.v2.c3p0.ComboPooledDataSource 请求特定连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39925469/

相关文章:

java - Oracle DB 时间戳到 Java 时间戳 : Confusion

java - Websphere MQ 连接池

postgresql - 最佳数据库连接池大小

java - 如何打造 Spring 的一池 bean ?

java - Android - 使用 ksoap2 使用 wsdl webservice 进行登录身份验证

java - 可以用实体字段持久化 JPA 实体吗?

java - 使用两个线程顺序调用两个不同函数时的通知/等待问题

java - tomee 中的此代码数据源配置在没有 Eclipse 的情况下运行正常,但是当我在 Eclipse 中运行时,它给出错误

c# - 与 Sqlexpress 连接

sql-server - 从 weblogic 12c 连接到 sql server