0

设想:

  1. 表有一行id=1
  2. 在行上使用 JDBC 启动更新命令,id=1但在提交之前,建立 JDBC 连接的 java 程序被终止
  3. 现在另一个 JDBC 连接尝试更新同一行id=1

观察:

监控数据库时,锁很明显,并且在同一行上进一步更新操作,导致数据库服务器冻结,必须重新启动才能正常操作......
如果更新查询较少且会话数较少,则锁获取一分钟内发布......但在现实世界的应用程序中,更新会频繁执行并且服务器会冻结

所以我的问题是:

有没有办法(配置,工具,...)强制,关闭和删除 Postgres 服务器中的锁,以处理来自客户端的任何死数据库连接

代码:

package postgrestest;

import java.sql.*;

public class IncompleteTransvanilla implements Runnable {
    private int seq = 0;
    private Connection connection = null;
    private boolean insertoperation = true;

    public static void main(String[] args) throws Exception{
        boolean flag = true;
        if(args.length>0) {flag = false;}
        for(int i=0;i<10;i++) {
            new Thread(new IncompleteTransvanilla(i,flag)).start();
            //Thread.sleep(1000*(int)(Math.random()*10));
        }
        Thread.sleep(10000);
    }

    public IncompleteTransvanilla(int i, boolean flag) {
        try {
            connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/testdb", "postgres", "postgres");
            connection.setAutoCommit(false);
        } catch (Exception e) {
            System.out.println("error");
        }
        seq=i;
        insertoperation = flag;
    }

    public void run() {
        try {
            PreparedStatement statement;
            if(insertoperation == true) {
                System.out.println("Inserting");
                statement = connection.prepareStatement("Insert into uacc(user_id,username,password,email) values(DEFAULT,?,'samplepass','samplemail')");
            }
            else {
                System.out.println("Updating");
                statement = connection.prepareStatement("update uacc set username=? where user_id=1");
            }
            int maxval = 100;
            for(int i=0;i<maxval;i++) {
                statement.setString(1, "sampleuser"+((seq*maxval)+i));
                statement.execute();
            }
            Thread.sleep(10000);
            connection.commit();
        } catch (Exception e) {
            System.out.println("Connection failure.");
        }
    }

}

数据库监控破折号截图供参考:

数据库监控——pashviewer postgres9.0 锁

编辑: 服务器中的任何建议/配置可用于自动删除此类锁或配置以减少它等待连接并删除锁的时间?

或者...将 postgres9.0 升级到 9.5 会解决这些问题吗?

4

1 回答 1

1

为了防止客户端在工作过程中突然死机,您可以使用以下 PostgreSQL 参数:

  • tcp_keepalives_idle:将其设置为 60 之类的低值,以便服务器在一分钟不活动后探测客户端,并在客户端死机时终止会话。

  • idle_in_transaction_session_timeout:将此设置为甚至更低的值,因为没有事务应该长时间保持空闲状态。这将杀死持有锁时空闲的会话。请注意不要破坏数据库上的正常活动!

从 9.0 升级应该是您的首要任务,因为 9.0 已经过时且不受支持,非常危险。更新到 v11 而不是 9.5。

于 2019-02-13T11:44:16.647 回答