Java的`synchronized`关键字似乎不起作用。

huangapple go评论74阅读模式
英文:

Java synchronized keyword doesn't seem to work

问题

我的要求是从数据库表中提取代码并将其标记为已删除,以便不再提取。我们注意到同一个代码被提取了两次。因此,我按以下方式同步了该方法:

public synchronized String fetchCode(School school) {

log.info("fetching code for school id : {}", school.getId());
//DB query to fetch the code (For a certain school id, there can be many codes and we need to use one at a time and delete it)
log.info("fetched code : {}", code);
//DB query to mark the code as deleted
return code;
}

在调试时,我注意到日志连续两次打印第一个日志,然后是第二个日志。而且两个日志中的代码是相同的。所以,似乎同步关键字没有起作用。有什么想法?

英文:

My requirement is to fetch a code from the table in the database and mark it as deleted so that it is never fetched again. We noticed that twice the same code was being fetched. So, I synchronized the method as below:

public synchronized String fetchCode(School school) {

log.info("fetching code for school id : {}", school.getId());
//DB query to fetch the code (For a certain school id, there can be many codes and we need to use one at a time and delete it)
log.info("fetched code : {}", code);
//DB query to mark the code as deleted
return code;
}

While debugging, I notice that the logs print the first log twice consecutively and then the second log. And the code was the same in both the logs. So, it seems the synchronized keyword is not doing any good. Any ideas?

答案1

得分: 1

我不打算触碰 Kafka 的部分,因为无论流处理项目产生了多么出色的结果,同步都必须进行,而同步从来都不容易——无论并行化迷恋者试图向您推销什么。

如果您想正确执行此操作,那么将信号量锁定尽可能地靠近数据。当您从数据库中获取要标记为已删除的记录时,请使用 for update 限定符。这将锁定数据库管理系统中的这些记录,并阻止其他进程发出对相同记录的 select...for update。它还会阻止其他进程对这些记录执行 updatedelete 操作。

有关在 select 上指定锁定的文档和示例可在PostgreSQL 文档中找到。

英文:

I am not going to touch the Kafka parts of this since as great as what that project has produced with respect to streaming may be, synchronization simply must be done, and synchronization is never easy--no matter what parallelization fetishists try to sell to you.

If you want to do this correctly, then move the semaphore locking as close to the data as you can. When you fetch the record(s) to be marked deleted from the database, use the for update qualifier. This will lock those records in the DBMS and block any other processes from issuing select...for update on those same records. It will also block any other processes issuing an update or delete on those records.

Documentation and examples of specifying locks on select can be found in the PostgreSQL documentation.

huangapple
  • 本文由 发表于 2020年8月8日 04:58:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63309061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定