【问题标题】:PostgreSQL not releasing locks from tablePostgreSQL 没有从表中释放锁
【发布时间】:2023-03-03 21:50:01
【问题描述】:

我们正在将我们的应用程序数据从 Oracle 迁移到 PostgreSQL。

环境详情:
Java 1.8
PostgreSQL 9.5 企业版(XA 数据源)
休眠 4.3
WildFly 9.0.2

我们正在使用他们网站上提供的最新 PostgreSQL 驱动程序(postgresql-9.4.1212.jdbc42.jar)(https://jdbc.postgresql.org/download.html)

编辑:还尝试了 postgres 企业数据库附带的 edb-jdbc17.jar 驱动程序。结果还是一样。

我们还在postgresql.conf 文件中将max_prepared_connections 设置为100。

下面给出的方法是获取一个对象并使用休眠启动事务然后提交事务。方法没有抛出任何错误或异常。但是在数据库中,对象没有被保存,应用程序正在获取表上的锁,这导致了死锁。 相同的代码与 Oracle 完美配合。

public void createObject(Object obj) throws CSTransactionException {
    Session s = null;
    Transaction t = null;
    try {

        try {
            obj = performEncrytionDecryption(obj, true);
        } catch (EncryptionException e) {
            throw new CSObjectNotFoundException(e);
        }


        try{
            obj = ObjectUpdater.trimObjectsStringFieldValues(obj);
        }catch(Exception e){
            throw new CSObjectNotFoundException(e);
        }



        s = HibernateSessionFactoryHelper.getAuditSession(sf);
        t = s.beginTransaction();
        s.save(obj);
        t.commit();
        s.flush();
        auditLog.info("Creating the " + obj.getClass().getName().substring(obj.getClass().getName().lastIndexOf(".")+1) + " Object ");          
    } 
catch (PropertyValueException pve)
    {
        try {
            t.rollback();
        } catch (Exception ex3) {
            if (log.isDebugEnabled())
                log.debug("Authorization|||createObject|Failure|Error in Rolling Back Transaction|" + ex3.getMessage());
        }
        if (log.isDebugEnabled())
            log
                    .debug("Authorization|||createObject|Failure|Error in Rolling Back Transaction|" + pve.getMessage());
        throw new CSTransactionException(
                "An error occured in creating the " + StringUtilities.getClassName(obj.getClass().getName()) + ".\n" + " A null value was passed for a required attribute " + pve.getMessage().substring(pve.getMessage().indexOf(":")), pve);
    }
    catch (ConstraintViolationException cve)
    {
        try {
            t.rollback();
        } catch (Exception ex3) {
            if (log.isDebugEnabled())
                log.debug("Authorization|||createObject|Failure|Error in Rolling Back Transaction|" + ex3.getMessage());
        }
        if (log.isDebugEnabled())
            log
                    .debug("Authorization|||createObject|Failure|Error in Rolling Back Transaction|" + cve.getMessage());
        throw new CSTransactionException(
                "An error occured in creating the " + StringUtilities.getClassName(obj.getClass().getName()) + ".\n" + " Duplicate entry was found in the database for the entered data" , cve);
    }       
    catch (Exception ex) {
        log.error(ex);
        try {
            t.rollback();
        } catch (Exception ex3) {
            if (log.isDebugEnabled())
                log
                        .debug("Authorization|||createObject|Failure|Error in Rolling Back Transaction|"
                                + ex3.getMessage());
        }
        if (log.isDebugEnabled())
            log
                    .debug("Authorization|||createObject|Failure|Error in creating the "
                            + obj.getClass().getName()
                            + "|"
                            + ex.getMessage());
        throw new CSTransactionException(
                "An error occured in creating the "
                        + StringUtilities.getClassName(obj.getClass()
                                .getName()) + "\n" + ex.getMessage(), ex);
    } finally {
        try {

            s.close();
        } catch (Exception ex2) {
            if (log.isDebugEnabled())
                log
                        .debug("Authorization|||createObject|Failure|Error in Closing Session |"
                                + ex2.getMessage());
        }
    }
    if (log.isDebugEnabled())
        log
                .debug("Authorization|||createObject|Success|Successful in creating the "
                        + obj.getClass().getName() + "|");
}

锁定数据库中的信息:

【问题讨论】:

  • 我不是 Hibernate 专家,我对 Postgres 有所了解 - Postgres 将锁定锁定到事务结束。您的代码不会结束交易。这是一个非常关键的问题。
  • t.commit();将保存并结束交易。
  • 查看 postgres - 记录所有语句或等待语句 - 也许 hibernate 不这样做。表 pg_stat_activity 或 log_min_duration_statement 选项可以帮助你。

标签: java postgresql hibernate wildfly-9


【解决方案1】:

您必须在提交后关闭会话(最好在 finally 块中):

s = HibernateSessionFactoryHelper.getAuditSession(sf);
t = s.beginTransaction();
    try {
            s.save(obj);
            session.flush();
            session.clear();  
            t.commit(); 
            auditLog.info("Creating the " + obj.getClass().getName().substring(obj.getClass().getName().lastIndexOf(".")+1) + " Object ");          
        }        
    }catch (Exception e) {
        t.rollBack();
    }finally{
        s.close();
    }

【讨论】:

  • 感谢 Maciej 的回复。我将在 finally 块中关闭会话。我刚刚粘贴了完整的方法定义。
  • @Leozeo 尝试在 Maciej 示例中声明的 t.commit() 之前创建 session.flush()
  • 在事务提交之前尝试刷新会话,但没有成功。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2021-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多