sql – 在非现有行上有“选择更新”块

前端之家收集整理的这篇文章主要介绍了sql – 在非现有行上有“选择更新”块前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们在应用程序中有一些持久性的数据,从服务器查询,然后存储在数据库中,以便跟踪附加信息.因为我们不想在内存中使用对象时查询,所以我们选择进行更新,以便其他要获取相同数据的线程将被阻止.

我不知道如何选择更新处理不存在的行.如果行不存在,另一个线程尝试在同一行执行另一个选择更新,该线程是否会被阻塞,直到另一个事务完成,否则还会得到一个空结果集?如果它只得到一个空的结果集,是否有任何方法使其阻止,例如,立即插入丢失的行?

编辑:

因为有一句话,我们可能会锁定太多,这里有一些关于我们案例具体用法的细节.在减少的伪代码中,我们的程序流程如下所示:

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

我既不是100%肯定,这实际上解决了这个问题,这个解决方案似乎还不错.所以如果有人必须提供更多的可用性这将是巨大的.

解决方法

I am not sure how select for update handles non-existing rows.

没有

你最好的办法就是使用一个咨询锁,如果你知道关于新行的独特之处. (如果需要,使用hashtext(),并且表的oid锁定它.)

最好的事情是桌子锁.

话虽如此,你的问题让你听起来像锁定的方式比你应该更多.实际上只需要锁定行,即写入操作.

猜你在找的MsSQL相关文章