Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何防止这两个应用程序同时更改共享数据?即使我已经使用了“选择更新”?_Java_Postgresql - Fatal编程技术网

Java 如何防止这两个应用程序同时更改共享数据?即使我已经使用了“选择更新”?

Java 如何防止这两个应用程序同时更改共享数据?即使我已经使用了“选择更新”?,java,postgresql,Java,Postgresql,我有两个带有共享数据库的应用程序。实际上,这两个应用程序正试图每x秒更新一行。该表如下所示: | host_name | acquired | attribute | | --------- | -------- | ---------- | | app1 | TRUE | 'xyz' | 在上表中,属性必须是唯一的。主机名可能会根据获取它的应用程序的不同而变化。因此,如果app2具有获取的属性,它将保持该属性x秒,然后将获取的设置为false,app2和app

我有两个带有共享数据库的应用程序。实际上,这两个应用程序正试图每x秒更新一行。该表如下所示:

| host_name | acquired | attribute  | 
| --------- | -------- | ---------- |
| app1      | TRUE     | 'xyz'      |
在上表中,属性必须是唯一的。主机名可能会根据获取它的应用程序的不同而变化。因此,如果app2具有获取的属性,它将保持该属性x秒,然后将获取的设置为false,app2和app1将竞相获取该属性,以再次获取特定属性


为此,我使用了postgres的select For update语句,因此如果app2获取了该属性,它将锁定该行,而app1在释放该锁定之前无法更改该行。我最初认为,选择更新是防弹的,但我错了。几天前,锁坏了。我假设app1和app2同时获得锁。我想知道我是否可以加强这一点,这样下次就不会发生了。有什么建议吗?

在您的update语句中,尝试类似这样的更改主键ID的方法,希望主键是integer或bigint

select * from my_table
where attribute='xyz'
and pg_try_advisory_lock(id)
for update
别忘了跑步

pg_advisory_unlock() 

当你处理完这一行后。

没有什么是防弹的。这只是软件。你可以尝试一种更乐观的方法。 将“更新计数器”行添加到表中。 在更新行之前,您读取该行以获取当前计数器值,并在update语句中添加where条件以确保仅在其他进程未更改计数器时更新该行

执行后,检查行是否已更改。如果是,一切都好。如果没有,请在出现故障时执行任何操作。

app1和app2同时获得锁-这是不可能的。Postgres事实上没有一个DBMS允许两个不同的事务在同一行上获取锁。
Update my_table set x=y, counter=counter+1 where counter=read_before