【问题标题】:setReadOnly not working on PostgreSQL ConnectionsetReadOnly 不适用于 PostgreSQL 连接
【发布时间】:2020-07-27 13:46:41
【问题描述】:

我在使用 JDBC 设置与 PostgreSQL 数据库的只读连接时遇到问题。

我正在创建一个应用程序,它加载要从文件执行的查询,并且我只想执行 SELECT(只读)查询。为将运行应用程序的用户设置权限不是一种选择,因此通过Connection.setReadOnly(boolean) 方法在代码级别设置权限是我能想到的唯一选择。

现在的问题是我尝试了我的应用程序进行插入和删除查询并且它们运行正常,所以我的解决方案不起作用。

关于如何解决问题的任何提示?

下面是我正在测试的简单代码 sn-p:

public class Test{

public static void main(String[] args) {
    connectAndExecute();
}

public static void connectAndExecute() {
    try {
        Class.forName("org.postgresql.Driver");
    } catch (ClassNotFoundException e1) {
        e1.printStackTrace();
        return;
    }

    Connection connection;

    String connString = "jdbc:postgresql://localhost:5432/testdb";
    try {
        connection = DriverManager.getConnection(connString, "user", "password");
    } catch (SQLException e) {
        e.printStackTrace();
        return;
    }

    try {
        connection.setReadOnly(true);
        connection.createStatement().execute("delete from testtable");
        // connection.createStatement().execute("insert intotesttable(testfield1)values('test')");
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

这是我正在使用的 JDBC 驱动程序

<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.10</version>

PostgreSQL 版本:11.6

【问题讨论】:

  • 如果你在数据库中执行SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY(这是setReadOnly(true)所做的)并尝试执行这些删除和插入,会发生什么?
  • setReadOnly() 似乎只有在禁用自动提交时才有效
  • 谢谢!它适用于建议的两种情况。我尝试了“设置会话特征”查询并禁用自动提交,在这两种情况下插入和删除查询都正确引发了异常。您对更喜欢哪种解决方案有什么建议吗?
  • 这听起来像是一个应该报告给 pgjdbc 驱动团队的错误。在任何情况下,您都应该更喜欢使用 JDBC API 而不是使用特定于数据库的命令,即使只是为了可移植性。
  • 谢谢大家,请添加已接受的答案,同时解决两种解决方法

标签: java postgresql jdbc readonly


【解决方案1】:

问题似乎与驱动程序的错误有关。

这两种解决方法都对我有用:

  • 由 kayaman 提议:

先执行sql命令

SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY
  • 由 a_horse_with_no_name 提议:

禁用自动提交会使 setReadOnly 调用生效

Connection.setAutoCommit(false);
Connection.setReadOnly(true);

【讨论】:

    【解决方案2】:

    明确一点:setReadOnly 方法的规范并不旨在防止更新数据库。

    正如 Java 的 API 所说:

    https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#setReadOnly-boolean-

    “将此连接置于只读模式,作为驱动程序启用数据库优化的提示”

    因此,依靠这种方法来保护与需要只读事务相关的任何事情并不是一个好主意:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-23
      • 1970-01-01
      • 2020-05-09
      • 2013-12-02
      • 1970-01-01
      • 2018-11-24
      相关资源
      最近更新 更多