我们从服务器中查询并存储在数据库中,因此我们可以跟踪其他信息。因为我们不想查询什么时候在内存中使用对象,selectfor update所以我们这样做是为了阻止其他想要获取相同数据的线程。 * u; y1 E7 g( r5 B# K4 z我不确定select for update处理不存在的行。如果不存在,尝试另一个线程select forupdate在同一行中执行另一个操作,线程是否会被阻塞,直到另一个事务完成,或者它会得到一个空的结果集?如果它只得到一个空的结果集,是否有办法阻止它,比如立即插入丢失的行? " c" z; k4 U; `: q$ ~$ w, J& H# Z编辑:+ E. V/ k& j# P3 P4 K4 S+ b
因为有一种说法,我们可能会锁定太多,这里有更多关于我们案例中具体用法的细节。我们的程序流程如下:) z; Z* ]" \ m2 q
d = queue.fetch();r = SELECT * FROM table WHERE key = d.key() FOR UPDATE;if r.empty() then r = get_data_from_somewhere_else();new_r = process_stuff( r );if Data was present then update row to new_relse insert new_r该代码在多线程中运行,从队列中获得的数据可能与数据库中的同一行(因此锁定)有关。然而,如果多个线程正在使用需要同一行的数据,则需要对这些线程进行排序(顺序无关紧要)。然而,如果没有银行,排名将失败,因为我们没有锁。* k: M' T+ v- Z% `4 N: ^ 编辑: ! @% T" |2 i3 T1 T2 G7 R目前,我有以下解决方案,这对我来说似乎很丑hack。 - G- i& \3 p# l6 Yselect the data for updateif zero rows match then insert some dummy data // this will block if multiple transactions try to insert if insertion failed then // somebody beat us at the race select the data for updatedo processingif data was changed then update the old or dummy dataelse rollback the whole transaction我不能100%确定这真的能解决问题,也不能保证它看起来不错。因此,如果有人必须提供更多可用的功能,那就太好了。 ) j1 `) I2 J- [ * f: M# `' [/ w' I2 A8 y解决方案: . {% j6 S, g5 j 我不确定如何选择更新来处理不存在的行。* T4 C% ?9 {- v
没有。! q* t |$ u8 K& ^6 B6 {
如果你知道新行的独特之处,最好的办法就是使用咨询锁。(如有必要,请使用hashtext(),使用表oid锁定。 y/ `% w% Y. O6 }# Y& T9 X下一件最好的事就是表锁。 6 N& }! z8 B0 ]* X4 `- c尽管如此,但你的问题听起来像是你的锁定方式超出了你应有的程度。只有在实际需要时才能锁定行,即写作操作。