Eri*_*ski 20 java postgresql exception
postgresql中导致此错误的原因是什么?
org.postgresql.util.PSQLException: ERROR: canceling statement due to user request
Run Code Online (Sandbox Code Playgroud)
我的软件版本:
PostgreSQL的 9.1.6 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2), 64-bit".
我的postgresql驱动程序是: postgresql-9.2-1000.jdbc4.jar
使用java版本: Java 1.7
线索:我的postgresql数据库位于固态硬盘上,此错误随机发生,有时根本不发生.
小智 17
我们已经找出了这个问题的原因.最新JDBC驱动程序9.2-100x中的setQueryTimeout()错误实现解释了这一点.如果手动打开/关闭连接可能不会发生,但是经常发生连接池并且autocommit设置为false.在这种情况下,应该使用非零值调用setQueryTimeout()(例如,使用Spring框架@Transactional(timeout = xxx)注释).
事实证明,只要在语句执行期间引发SQL异常,取消计时器就不会被取消并保持活动状态(这就是它的实现方式).由于池,后面的连接没有关闭,但返回到池中.稍后,当取消计时器触发时,它会随机取消当前与此计时器创建的连接相关联的查询.此时,这是一个完全不同的查询,它解释了随机性效应.
建议的解决方法是放弃setQueryTimeout()并改为使用PostgreSQL配置(statement_timeout).它没有提供相同水平的灵活性,但至少总是有效.
如果您在不使用事务的情况下收到此错误
用户已请求取消该语句。声明正在做它被告知要做的事情。问题是,谁要求取消这个声明?
查看代码中准备执行 SQL 的每一行。您可以有一些适用于在某些情况下取消语句的语句的方法,如下所示:
statement = conn.createStatement();
conn.setAutoCommit(true);
statement.setQueryTimeout(25);
my_insert_statement.setString(1, "moobars");
my_insert_statement.executeUpdate();
statement.close();
Run Code Online (Sandbox Code Playgroud)
在我的情况下,发生的事情是我将查询超时设置为 25 秒,而插入时间比这更长。它通过了“由于用户请求而取消声明”的异常。
如果您在使用事务时遇到此错误:
如果您收到此异常,请仔细检查所有执行 SQL 事务的代码。
如果您有一个在事务中的查询并且您忘记提交,然后您使用该连接执行其他操作,就像您不在事务中一样操作,则可能存在产生此异常的未定义行为。
确保所有执行事务的代码都在自行清理。确保事务开始、工作完成、更多工作完成、事务回滚或提交,然后确保连接处于该autocommit=true状态。
如果这是您的问题,那么在您忘记自己清理之后不会抛出异常,它发生在您在事务后未能清理很久之后的某个地方,这使得这是一个难以追踪的异常。刷新连接(关闭它并获得一个新连接)将清除它。
这假设postgresql的jdbc jar文件中的竞争条件错误是造成上述错误的原因.(这里描述的竞争条件:http://postgresql.1045698.n5.nabble.com/ERROR-canceling-query-due-to-user-request-td2077761.html)
解决方法1,定期刷新与数据库的连接
一种解决方法是关闭与数据库的连接,并定期创建与数据库的新连接.每隔几千个sql语句关闭连接并重新创建它.然后由于某种原因不再抛出此错误.
解决方法2,打开日志记录
如果在设置驱动程序时打开JDBC驱动程序级别的日志记录,则在某些情况下会中断竞争条件问题:
Class.forName("org.postgresql.Driver");
org.postgresql.Driver.setLogLevel(org.postgresql.Driver.DEBUG);
Run Code Online (Sandbox Code Playgroud)
解决方法3,捕获异常并重新初始化连接
您还可以尝试捕获特定异常,重新初始化连接并再次尝试查询.
解决方法4,等到postgresql jdbc jar出现bug修复
我认为这个问题可能与我的SSD硬盘速度有关.如果你收到这个错误,请在这里发布如何一致地重现它,有开发人员非常有兴趣压缩这个bug.