gpt4 book ai didi

java - 如果遇到暂时性异常,我可以重新使用 PreparedStatement 吗?

转载 作者:可可西里 更新时间:2023-11-01 07:08:10 28 4
gpt4 key购买 nike

我有一段代码可以更新数据库中的记录。简化示例:

...
statement = connection.prepareStatement(
"INSERT INTO thistable (name) VALUES (?)",
PreparedStatement.RETURN_GENERATED_KEYS
);
statement.setString( 1, "Fred" );
statement.addBatch( );
statement.setString( 2, "Joe" );
statement.addBatch( );
statement.executeBatch( );
...

这是一些处理大量记录的代码的一部分,代码运行大量线程以提高速度。这一切都很好,但是随着实时环境中负载的增加,我注意到一些 SQLTransientException 被抛出。看来除了重试交易之外,我对这些无能为力。

我的问题是:即使声明失败,批处理是否已经被清除?我可以简单地重试 executeBatch 行,还是需要重新创建整个批处理?非批处理语句也是如此吗?


简而言之,更一般地说,这是处理暂时性异常的好方法吗?

statement.setString( 1, "Fred" );
statement.addBatch( );
statement.setString( 2, "Joe" );
statement.addBatch( );
for( int attempt = 0; ; attempt ++ ) {
try {
statement.executeBatch( );
break;
} catch( SQLTransientException ex ) {
if( attempt >= 3 ) {
throw ex;
}
try {
Thread.sleep( attempt * attempt * 100 );
} catch( InterruptedException ex2 ) {
throw ex;
}
}
}

最佳答案

API除以下情况外,没有提供有关 SQLTransientException 发生时的行为的太多信息

 when the driver has determined that the timeout value that was specified by the 
setQueryTimeout method has been exceeded and has at least attempted
to cancel the currently running Statement

验证了 Mysql JDBC4 实现。

根据我的观察,我可以看到如果超时可能会发生 SQLTimeoutException(即 SQLTransientException)。

超时时,它不仅清除了最后的语句,还清除了整个批处理(至少在 MYSQL 实现中)

// we timeout the entire batch, not individual statements

所以这部分很清楚。

并且按照 JDBC 规范

The statement’s batch is reset to empty once executeBatch returns

无论 executeBatch 是否抛出异常/成功,它都会清除 Batch。

特别是 Mysql Prepared Statement 在 executeBatch() 方法中的 finaly block 中清除批处理

finally {
this.statementExecuting.set(false);
clearBatch();
}

因此您的逻辑将不起作用,因为您没有再次将语句添加到批处理中。

因此将语句添加回批处理并重新执行。您很有可能会再次超时。所以先找时间出来。如果可能的话,在执行日志中写一些关于原因/状态的信息。

关于java - 如果遇到暂时性异常,我可以重新使用 PreparedStatement 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23768553/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com