我们在应用程序中有一些持久性的数据,从服务器查询,然后存储在数据库中,以便跟踪附加信息.因为我们不想在内存中使用对象时查询,所以我们选择进行更新,以便其他要获取相同数据的线程将被阻止.
我不知道如何选择更新处理不存在的行.如果行不存在,另一个线程尝试在同一行执行另一个选择更新,该线程是否会被阻塞,直到另一个事务完成,否则还会得到一个空结果集?如果它只得到一个空的结果集,是否有任何方法使其阻止,例如,立即插入丢失的行?
编辑:
因为有一句话,我们可能会锁定太多,这里有一些关于我们案例具体用法的细节.在减少的伪代码中,我们的程序流程如下所示:
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_r else insert new_r
该代码在多个线程中运行,从队列中获取的数据可能与数据库中的相同行(因此是锁)有关.但是,如果多个线程使用需要同一行的数据,那么这些线程需要按顺序排列(顺序并不重要).但是,如果行不存在,则该顺序化将失败,因为我们没有获得锁定.
编辑:
现在我有以下解决方案,这似乎是一个丑陋的黑客.
select the data for update if 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 update do processing if data was changed then update the old or dummy data else rollback the whole transaction
解决方法
I am not sure how select for update handles non-existing rows.
没有
你最好的办法就是使用一个咨询锁,如果你知道关于新行的独特之处. (如果需要,使用hashtext(),并且表的oid锁定它.)
最好的事情是桌子锁.
话虽如此,你的问题让你听起来像锁定的方式比你应该更多.实际上只需要锁定行,即写入操作.