如何重置 sql 连接池中的会话?
How to reset a session in a sql connection pool?
我有一个使用 javax.sql.DataSource
和 PostgreSQL JDBC 的连接池。这个过程很简单,我从连接池中获取一个虚拟连接,处理它,然后关闭虚拟连接(释放到连接池的连接)。一切正常。
但是当我第二次获得相同的虚拟连接时,会话具有与上一次执行相同的数据。主要是上次执行时创建的temp tables。每次执行后如何重置会话?或者您可以建议任何变通方法来解决问题而不使用 creating temp table if not exists query syntax.
示例代码
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Base {
public Connection getConnection() {
Context ctx = (Context) new InitialContext().lookup("java:/comp/env");
DataSource ds = (DataSource) ctx.lookup("database");
Connection con = ds.getConnection();
return con;
}
public Connection closeConnection( Connection con){
if (con != null || !con.isClosed()) {
con.close();
}
}
context.xml =>
<Resource
accessToUnderlyingConnectionAllowed="true"
auth="Container"
closeMethod="close"
driverClassName="org.postgresql.Driver"
maxTotal="50"
maxWaitMillis="60000"
removeAbandonedOnBorrow="true"
maxIdle="20"
name="Database"
password="p*******"
type="javax.sql.DataSource"
url="jdbc:postgresql://dbUrl/dbName"
username="dbUser"
validationQuery="select version();"
validationQueryTimeout="60"
/>
// 用例
con = getconnection()
CallableStatement st = con.prepareCall("{ doSomething()}");
st.execute()
//processing
st.close()
con.close()
在 doSomething() plpgsql 函数中,我有临时 table 创建(名称 t_table)、数据处理和数组输出。当我从 java 中反复调用它时,第一次执行是成功的。但是从第二个执行消息说 t_table 已经存在被抛出。我认为在使用连接池时,池中的连接是会话独立的 IE。来自池的每个新连接都会有一个新会话。 PostgreSQL 解决方案是删除特定的临时文件 table 。但是 tomcat 方面没有其他解决方案 ?
discard temporary
命令可用于清理会话。
当连接 返回 到池时,您可以将其配置为 运行 的验证查询。
对于 Tomcat JDBC 池,这将是这样的:
validationQuery="discard temporary"
testWhileIdle="false"
testOnBorrow="false"
testOnReturn="true"
如果您想进一步清理会话,可以考虑使用 discard all
,但这需要启用自动提交,不确定是否适合您。
如果不允许这样的语句,你可以把它包装成一个函数:
create function session_cleanup()
returns boolean
as
$$
discard temporary;
select true;
$$
language sql;
validationQuery="select session_cleanup()"
testWhileIdle="false"
testOnBorrow="false"
testOnReturn="true"
我有一个使用 javax.sql.DataSource
和 PostgreSQL JDBC 的连接池。这个过程很简单,我从连接池中获取一个虚拟连接,处理它,然后关闭虚拟连接(释放到连接池的连接)。一切正常。
但是当我第二次获得相同的虚拟连接时,会话具有与上一次执行相同的数据。主要是上次执行时创建的temp tables。每次执行后如何重置会话?或者您可以建议任何变通方法来解决问题而不使用 creating temp table if not exists query syntax.
示例代码
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Base {
public Connection getConnection() {
Context ctx = (Context) new InitialContext().lookup("java:/comp/env");
DataSource ds = (DataSource) ctx.lookup("database");
Connection con = ds.getConnection();
return con;
}
public Connection closeConnection( Connection con){
if (con != null || !con.isClosed()) {
con.close();
}
}
context.xml =>
<Resource
accessToUnderlyingConnectionAllowed="true"
auth="Container"
closeMethod="close"
driverClassName="org.postgresql.Driver"
maxTotal="50"
maxWaitMillis="60000"
removeAbandonedOnBorrow="true"
maxIdle="20"
name="Database"
password="p*******"
type="javax.sql.DataSource"
url="jdbc:postgresql://dbUrl/dbName"
username="dbUser"
validationQuery="select version();"
validationQueryTimeout="60"
/>
// 用例
con = getconnection()
CallableStatement st = con.prepareCall("{ doSomething()}");
st.execute()
//processing
st.close()
con.close()
在 doSomething() plpgsql 函数中,我有临时 table 创建(名称 t_table)、数据处理和数组输出。当我从 java 中反复调用它时,第一次执行是成功的。但是从第二个执行消息说 t_table 已经存在被抛出。我认为在使用连接池时,池中的连接是会话独立的 IE。来自池的每个新连接都会有一个新会话。 PostgreSQL 解决方案是删除特定的临时文件 table 。但是 tomcat 方面没有其他解决方案 ?
discard temporary
命令可用于清理会话。
当连接 返回 到池时,您可以将其配置为 运行 的验证查询。
对于 Tomcat JDBC 池,这将是这样的:
validationQuery="discard temporary"
testWhileIdle="false"
testOnBorrow="false"
testOnReturn="true"
如果您想进一步清理会话,可以考虑使用 discard all
,但这需要启用自动提交,不确定是否适合您。
如果不允许这样的语句,你可以把它包装成一个函数:
create function session_cleanup()
returns boolean
as
$$
discard temporary;
select true;
$$
language sql;
validationQuery="select session_cleanup()"
testWhileIdle="false"
testOnBorrow="false"
testOnReturn="true"