简体   繁体   English

JDBC批量更新问题

[英]JDBC Batch Update Problem

I have a slightly unique requirement with the Java-JDBC API along with Oracle Database. 我对Java-JDBC API以及Oracle数据库有一点点独特的要求。 I have autoCommit to be default which is true for Oracle and I am using the example similar to this link . 我有autoCommit是默认值,这对Oracle来说是正确的,我使用类似于此链接的示例。

However, when I add say 1000 batches and lets say each of them are inserts. 但是,当我添加说1000批时,让我们说每个都是插入。 And Let us assume that about 20 records violated some constraints, I want the remaining 980 to go COMMITTED (and henceforth visible to any other queries using any other connection) to the database and ignore the 20 records. 让我们假设大约有20条记录违反了某些约束条件,我希望剩下的980条记录对数据库进行COMMITTED(以后对任何其他连接的任何其他查询都可见)并忽略20条记录。 In the above example, when one row violates any transaction then even when I commit in the catch block the transaction only commits until the first failure . 在上面的示例中,当一行违反任何事务时, 即使我在catch块中提交,事务也只会提交直到第一次失败

I know batch updates are to be done ONLY when you are fairly sure all rows will go through and exception processing is not one, but am planning to PATCH an existing database so some kind of "bad practices" is okay :) Any code samples will be highly appreciated. 我知道批量更新只有在你相当确定所有行都会通过并且异常处理不是一个时才会完成,但是我打算修补现有数据库所以某种“不良做法”是好的:)任何代码示例都会非常感谢。

**** MORE DETAILS **** **** 更多细节 ****

Using Simple insert/update is not okay since I am processing close to 3M rows so am batching every 1000 records. 使用简单插入/更新是不行的,因为我处理接近3M行,所以每1000条记录批处理。 Simply adding 1000 inserts in loop (ignoring exceptions) takes way more time (about 5 seconds for every 1000 records) as opposed to the batch update < 300ms. 简单地在循环中添加1000个插入(忽略异常)会占用更多时间(每1000个记录大约5秒),而批量更新<300ms。

Problem: With Oracle database the Driver seems to stop at the first FAILURE, ie when 1000 rows are batched and 100th failed, I want it to go ahead till the 1000th row. 问题:对于Oracle数据库,驱动程序似乎在第一次失败时停止,即当1000行被批处理并且第100次失败时,我希望它继续直到第1000行。 Me thinks this cannot be done in JDBC (with Oracle) Like the link indicates only few databases support such feature and probably Oracle is not one 我认为这不能在JDBC中完成(使用Oracle)就像链接表明只有少数数据库支持这样的功能,可能Oracle不是一个

You can use a PL/SQL stored procedure using the SAVE EXCEPTIONS clause which will allow you to issue a bulk update and then return those rows which could not be updated. 您可以使用SAVE EXCEPTIONS子句使用PL / SQL存储过程,该子句允许您发出批量更新,然后返回无法更新的行。 Here is a couple of example links: 以下是几个示例链接:

http://rwijk.blogspot.com/2007/11/save-exceptions.html http://rwijk.blogspot.com/2007/11/save-exceptions.html

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8912264456901 http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8912264456901

您应该插入到没有约束的工作表中,然后删除或修复违反的内容,并将其余部分INSERT SELECT到单个SQL语句中的实际表中。

Could you try the Oracle merge-when-not-matched statement? 您可以尝试Oracle merge-when-not-matched语句吗? Example: http://www.idevelopment.info/data/Oracle/DBA_tips/SQL/SQL_14.shtml 示例: http//www.idevelopment.info/data/Oracle/DBA_tips/SQL/SQL_14.shtml

You could try this: Start with batches of 50 or 100. (Choose a size so they have a good probablity to be processed successfully). 您可以尝试这样:从50或100批次开始。(选择一个大小,以便它们具有良好的可能性,以便成功处理)。 Those which fail, process one-by-one. 那些失败的,一个一个地处理。

Other possibility: Disable the constraints, load the data, delete those rows which violate the constraints. 其他可能性:禁用约束,加载数据,删除违反约束的行。

我应首先检查是否存在约束违规,而不是在没有违反约束的情况下插入该记录。

I was looking some solution on the line of "With Oracle database the Driver seems to stop at the first FAILURE, ie when 1000 rows are batched and 100th failed, I want it to go ahead till the 1000th row." 我正在寻找一些解决方案“使用Oracle数据库,驱动程序似乎在第一次失败时停止,即当1000行被批处理并且第100次失败时,我希望它继续直到第1000行。” Basically I wanted to know if this can be done with Oracle JDBC driver. 基本上我想知道是否可以使用Oracle JDBC驱动程序完成此操作。

However a variety of answers have been proposed (most/all of which I had already considered) 1) Disabling the constraints/load data/remove offending rows/repeat this many times 2) Do all the checking before loading data 3) Decrease the batch size to 50 - 100. 然而,已经提出了各种答案(我已经考虑过的大部分/全部)1)禁用约束/加载数据/删除违规行/重复这么多次2)在加载数据之前进行所有检查3)减少批次大小为50 - 100。

Unfortunately my checking cannot be done before loading and making batch size to be 50 or 100 means taking more time to do the 5M rows I have (infact the total time increased to a few hours instead of 40 mins with a batch size of 1000). 不幸的是,我的检查无法在装载之前进行,批量大小为50或100意味着需要更多时间来完成我所拥有的5M行(事实上总时间增加到几小时而不是40分钟,批量大小为1000)。 I have resorted to keeping the batch size of 1000 ACCEPTING THE problem as is and put the code under a "while" loop and do the job until we fill up all rows. 我已经采取保持批量大小为1000接受问题的原样 ,并将代码放在“while”循环下并完成工作直到我们填满所有行。

Like I said, since there is NO WAY WITH ORACLE BATCH JDBC to proceed after first failure, the answer to this question will be "NOT DOABLE" and just accept the constraints and document the fact that this tool takes about 40 mins to complete :) 就像我说的那样,因为在第一次失败后没有ORACLE BATCH JDBC的继续,所以这个问题的答案将是“不可行”并且只接受约束并记录这个工具需要大约40分钟才能完成的事实:)

Have an exceptions table and make sure your proc never raises exception but saves all exceptions in database. 有一个例外表,并确保您的proc永远不会引发异常但保存数据库中的所有异常。 Once all done, query exceptions table and see records could not go through. 完成所有操作后,查询异常表并查看记录无法通过。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM