java - 如何在jdbc中为事务设置局部变量
问题描述
我正在开发一个项目,我需要在其数据库中初始化会话变量。如果我直接使用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();
}
但问题仍然存在。如何SET
打电话JDBC
解决方案
我认为您需要在DataSource
not上执行此操作Connection
。
我postgresql
知道的唯一方法是下变频。就像是:
DataSource myDS = getDataSource();
if (DataSource instanceof BaseDataSource.class) {
BaseDataSource pgDS = (BaseDataSource) myDS; // expose setProperty method
pgDS.setProperty("app.user_id", "0000");
}
您将其放置在应用程序中的哪个位置显然取决于您的问题中未提供的许多细节。
推荐阅读
- multithreading - 在阻塞函数的背景下会发生什么?
- c++ - 为什么在这个例子中需要后期绑定?
- sql - Django ORM按日期从日期时间分组,分组聚合
- node.js - 还有另一个 Promise 问题 - 嵌套 Sequelize 调用?
- mysql - 不同时间和同一天 SQL 之间的结果
- amazon-web-services - AWS 中是否有相当于 docker configs 的服务?
- excel - 基于单元格值的删除行宏总是删除第一行
- php - 解析 onesignal API 响应
- r - 如何从 R 上的矩阵返回 1 列值?
- mysql - 为什么我的 rake 任务在测试运行期间无法连接到我的 MySQL 实例?