我需要同时在四个无数线程中执行以下操作(嗯,可能更接近 2 个线程,但无论哪种方式......):如果某某不存在,请插入它。
目前,该应用程序说:
select rows from the db
if row count == 0,
do some stuff
insert a row
我有一种情况,它同时在 2 个单独的线程中运行。这样,两个线程可以(实际上到目前为止每次都这样做)在任一线程插入行之前检查现有行;因此我们有重复的行。这是不好的。
我能想到的所有算法都不尽如人意。
例如,如果我这样做:
open tx
insert a row
select rows
if row count > 2, rollback
else commit
当事务使用READ_COMMITTED
隔离时,一个线程将看不到另一个线程的插入行,并且可能出现重复。通过READ_UNCOMMITTED
隔离,每个线程都可以看到另一个线程的行,并且两者都会回滚。我想如果我使用MERGE
语句而不是插入然后选择(反之亦然),我会遇到同样的问题。
当上述算法同时执行时,是否有一种算法可以用来保证恰好插入 1 行?FWIW,我在 Spring 中使用 DB2、mybatis 和基于 xml 的 tx 管理,但如果可能的话,我很乐意从其他方面进行翻译。
在并发方面我是新手,所以如果这个问题揭示了您所知道的书籍或文章所弥补的无知,请分享。
编辑:
上面的插入语句是懒惰地授予用户一些东西,如果他们没有的话。在这种情况下,唯一性约束将是合适的。然而,在应用程序的其他地方,它是不合适的。:(
我很快就会使这个例子更具体一些,这样更容易理解。