Java选择性同步

Rne*_*net 1 java multithreading thread-safety

我正在维护一个非常旧的应用程序,最近我遇到了一个"多线程"错误.这里,在一个方法中,要将值插入到db中,首先检查记录是否存在,然后如果它不存在,则将其插入到db中.

createSomething(params)
{
  ....
  ....
  if( !isPresentInDb(params) )
  {
    .....
    .....
    .....
    insertIntoDb(params)
   }
 ...
 }
Run Code Online (Sandbox Code Playgroud)

这里,当多个线程调用此方法时,具有相同参数的两个或多个线程可以通过isPresentInDb检查,一个线程成功插入,其他线程失败.

为了解决这个问题,我将db交互包含在一个synchronized(this)块中.但有更好的方法吗?

编辑:它更像是选择性同步,只需要同步具有相同参数的线程.选择性同步可能吗?

Dav*_*veH 8

我想说更好的方法就是尽可能让数据库为你做.假设您想要更新或插入的数据库上的行对其有唯一约束,那么我通常的方法是

  • 无条件地插入行
  • 如果发生SQLException,请检查它是否是由插入错误上的重复键引起的,如果是,则执行更新,否则重新抛出SQLException.

如果您可以将这些语句包装在数据库事务中,那么您不必担心两个线程相互踩踏.


Sea*_*wen 5

如果逻辑真的是"如果它还不存在则创建它",那么将逻辑推入数据库可能更好.例如,MySQL具有"INSERT IGNORE"语法,如果它违反主键约束,将导致它忽略插入.您的代码可能无法实现,但值得考虑.