如何在jdbc中为事务设置局部变量
Posted
技术标签:
【中文标题】如何在jdbc中为事务设置局部变量【英文标题】:how to set local variable for transaction in jdbc 【发布时间】:2018-11-02 11:17:39 【问题描述】:我正在开发一个项目,我需要在其数据库中初始化会话变量。如果我直接使用sql,初始化是用SET
语句完成的
set local app.user_id to "0000";
我尝试用Connection#setClientInfo()
初始化它,但失败了
try(Connection connection = getDataSource().getConnection())
boolean isAutoCommit = connection.getAutoCommit();
try
Properties properties = new Properties();
properties.put("app.user_id", "0000");
connection.setAutoCommit(false);
connection.setClientInfo(properties);
String query = "insert into positions (name, description) values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query))
statement.setString(1, position.getName());
statement.setString(2, position.getDescription());
statement.executeUpdate();
connection.commit();
catch (SQLException e)
e.printStackTrace();
connection.rollback();
finally
connection.setAutoCommit(isAutoCommit);
我得到PSQLException
(插入查询依赖于参数,它没有通过)
org.postgresql.util.PSQLException: ERROR: unrecognized configuration parameter "app.user_id"
如果我使用PreparedStatement
,我会收到带有消息的PSQLException
ERROR: syntax error at or near "$1"
try(Connection connection = getDataSource().getConnection())
boolean isAutoCommit = connection.getAutoCommit();
try
connection.setAutoCommit(false);
try(PreparedStatement statement = connection.prepareStatement("set local app.user_id to ?"))
statement.setString(1, "0000");
statement.execute();
String query = "insert into positions (name, description) values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query))
statement.setString(1, position.getName());
statement.setString(2, position.getDescription());
statement.executeUpdate();
connection.commit();
catch (SQLException e)
e.printStackTrace();
connection.rollback();
finally
connection.setAutoCommit(isAutoCommit);
唯一的方法是直接使用固定值执行查询。但在这样做时,我不得不使用连接来构建查询。而且我不想这样做。
try(Connection connection = getDataSource().getConnection())
boolean isAutoCommit = connection.getAutoCommit();
try
connection.setAutoCommit(false);
try(Statement statement = connection.createStatement())
statement.execute("set local app.user_id to 0000");
String query = "insert into positions (name, description) values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query))
statement.setString(1, position.getName());
statement.setString(2, position.getDescription());
statement.executeUpdate();
connection.commit();
catch (SQLException e)
e.printStackTrace();
connection.rollback();
finally
connection.setAutoCommit(isAutoCommit);
初始化这些参数的正确方法是什么? 我使用 PostgreSQL 11、JDBC 4.2(带有驱动程序 42.2.5)和 DBCP 2.5
编辑
我是通过致电set_config
做到的。
try(PreparedStatement statement = connection.prepareStatement("select set_config(?, ?, true)"))
statement.setString(1, "app.user_id");
statement.setString(2, "0000");
statement.execute();
但问题仍然存在。如何在JDBC
中调用SET
【问题讨论】:
【参考方案1】:我认为您需要在 DataSource
而不是 Connection
上执行此操作。
在postgresql
我知道的唯一方法是下转换。比如:
DataSource myDS = getDataSource();
if (DataSource instanceof BaseDataSource.class)
BaseDataSource pgDS = (BaseDataSource) myDS; // expose setProperty method
pgDS.setProperty("app.user_id", "0000");
您将其放置在应用程序中的哪个位置显然取决于您的问题中未提供的许多细节。
【讨论】:
我用org.apache.commons.dbcp2.BasicDataSource
以上是关于如何在jdbc中为事务设置局部变量的主要内容,如果未能解决你的问题,请参考以下文章