多次重用PreparedStatement
如果在没有任何池的情况下使用带有单个公共连接的PreparedStatement,我可以为每个 dml/sql 操作重新创建一个实例来保持准备好的语句的功能吗?
我的意思是:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
而不是:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
我的问题是由于我想将此代码放入多线程环境中而产生的,您能给我一些建议吗?谢谢
in the case of using PreparedStatement with a single common connection without any pool, can I recreate an instance for every dml/sql operation mantaining the power of prepared statements?
I mean:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
instead of:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
my question arises by the fact that I want to put this code into a multithreaded environment, can you give me some advice? thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第二种方法稍微高效一些,但更好的方法是分批执行它们:
但是,您取决于 JDBC 驱动程序实现一次可以执行多少个批次。例如,您可能希望每 1000 个批次执行一次:
对于多线程环境,如果您在同一方法块内的尽可能短的范围内获取并关闭连接和语句,则无需担心这一点 根据正常的 JDBC 习惯用法,使用 try-with-resources 语句如上面的代码片段所示。
如果这些批次是事务性的,那么您希望关闭连接的自动提交,并且仅在所有批次完成时提交事务。否则,当第一批批次成功而后来的批次失败时,可能会导致数据库脏。
The second way is a tad more efficient, but a much better way is to execute them in batches:
You're however dependent on the JDBC driver implementation how many batches you could execute at once. You may for example want to execute them every 1000 batches:
As to the multithreaded environments, you don't need to worry about this if you acquire and close the connection and the statement in the shortest possible scope inside the same method block according the normal JDBC idiom using try-with-resources statement as shown in above snippets.
If those batches are transactional, then you'd like to turn off autocommit of the connection and only commit the transaction when all batches are finished. Otherwise it may result in a dirty database when the first bunch of batches succeeded and the later not.
您代码中的循环只是一个过于简化的示例,对吗?
最好只创建一次PreparedStatement,然后在循环中一遍又一遍地重复使用它。
在不可能的情况下(因为它使程序流程过于复杂),使用
PreparedStatement
仍然是有益的,即使您只使用它一次,因为工作的服务器端(解析SQL并缓存执行计划),仍然会减少。为了解决您想要重用 Java 端
PreparedStatement
的情况,某些 JDBC 驱动程序(例如 Oracle)具有缓存功能:如果您为以下对象创建PreparedStatement
在同一个连接上使用相同的 SQL,它会给你相同的(缓存的)实例。关于多线程:我不认为 JDBC 连接可以在多个线程之间共享(即由多个线程同时使用)。每个线程都应该从池中获取自己的连接,使用它,然后再次将其返回到池中。
The loop in your code is only an over-simplified example, right?
It would be better to create the
PreparedStatement
only once, and re-use it over and over again in the loop.In situations where that is not possible (because it complicated the program flow too much), it is still beneficial to use a
PreparedStatement
, even if you use it only once, because the server-side of the work (parsing the SQL and caching the execution plan), will still be reduced.To address the situation that you want to re-use the Java-side
PreparedStatement
, some JDBC drivers (such as Oracle) have a caching feature: If you create aPreparedStatement
for the same SQL on the same connection, it will give you the same (cached) instance.About multi-threading: I do not think JDBC connections can be shared across multiple threads (i.e. used concurrently by multiple threads) anyway. Every thread should get his own connection from the pool, use it, and return it to the pool again.