繁体   English   中英

解决并发更新/删除语句Java Oracle

[英]Solve Concurrent Update/Delete Statements Java Oracle

我现在遇到的问题是同时处理SQL UPDATEDELETE语句。 如果仅一个接一个地调用该程序,则没有问题,但是,如果两个人决定运行该程序,则可能会失败。

我的程序做什么:

有关食物的程序,所有程序都有描述和描述的日期。 当人们输入食物的描述时,它将被输入数据库,您可以在其中快速检索描述。 如果描述是旧的7天,那么我们deletedelete使其过时。 但是,如果用户使用不同的描述输入数据库中已有的食物,则我们将对其进行update并更改日期。 删除发生在更新/插入之后(将插入不需要更新的内容,然后程序检查数据库中是否有过时的内容并将其删除)。

问题:

有两个人运行该程序,一个人正试图更新食物,另一个人则将其清除,原因是刚完成就删除了食物。 更新不会发生,并且程序将继续其余的更新(<-我读这是因为我的驱动程序没有停止。某些驱动程序在出现错误时停止更新)。

我想做的事:

我希望我的程序在错误的更新处停止或抓住那个位置,然后重新启动进程/线程。 重新启动将包括梳理哪些食物需要更新或插入。 因此,不良记录将被移到插入方法而不是更新中。 更新将在中断处继续。 一切都很好。

我知道这不是唯一的方法,因此欢迎使用不同的方法来解决此问题。 upsert您可以使用upsert语句,但这也有竞争条件。 (关于upsert语句的问题:如果我使upsert方法同步,它将不会有竞争条件吗?)

谢谢

在Java代码中将事务级别设置为可序列化。 然后,您的语句应如下所示:

 update food_table set update_time = ? where ....
 delete from food_table where update_time < ?

无论哪种情况,您都可能会得到可序列化的异常。 如果是更新,则需要重新插入条目。 在第二种情况下,只需忽略并再次运行即可。

根据jout jdbc连接管理,对您的问题有不同的实用解决方案。

如果该应用程序是一个客户端服务器,并且它对每个客户端使用专用的持久连接(即,它在程序启动时打开jdbc连接,并在程序关闭时关闭),则可以使用select for update语句。 在向用户显示记录时,您必须发出选择更新选项,并且当用户执行其操作时,您将执行所需的操作并提交。 这种方法序列化了dabatabase操作,如果显示并锁定了多个记录,则可能不可行

当您的Web应用程序带有连接池或没有专用连接时,可以使用第二种方法进行读取和更新/删除操作。 在这种情况下,您有这种情况

用户1通过jdbc连接1选择其数据

用户2通过jdbc连接2选择其数据(与用户1相同)

用户2使用jdbc连接3提交导致某些删除的数据

用户1提交数据并进行大量更新,因为该数据已通过jdbc连接2删除

既然你不能真的在同一个JDBC连接锁定您读取数据,你可以发出一个select for update更新数据前,检查是否有数据。 如果您有数据,则可以对其进行更新(并且由于相同数据上的每个删除命令都在等待您选择更新终止,因此其他会话将不会删除它们); 如果您没有数据,因为它们在用户显示期间已被删除,则必须重新插入它们。 您的delete语句在date列上必须具有表示最后更新的过滤器。

您可以使用其他方法,并避免使用例如

  update food-table set last_update=? where id=? and last_update=<the last update you have in java  program> 

并且必须检查update语句是否确实更新了一行(在jdbc中,executeUpdate返回已修改的行数,但是如果使用的是“纯” JDBC或某种框架,则没有指定),并且它没有更新任何行您必须发出插入语句。

暂无
暂无

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

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