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

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

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

编辑:

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

  1. d = queue.fetch();
  2. r = SELECT * FROM table WHERE key = d.key() FOR UPDATE;
  3. if r.empty() then
  4. r = get_data_from_somewhere_else();
  5.  
  6. new_r = process_stuff( r );
  7.  
  8.  
  9. if Data was present then
  10. update row to new_r
  11. else
  12. insert new_r

代码在多个线程中运行,从队列中获取的数据可能与数据库中的相同行(因此是锁)有关.但是,如果多个线程使用需要同一行的数据,那么这些线程需要按顺序排列(顺序并不重要).但是,如果行不存在,则该顺序化将失败,因为我们没有获得锁定.

编辑:

现在我有以下解决方案,这似乎是一个丑陋的黑客.

  1. select the data for update
  2. if zero rows match then
  3. insert some dummy data // this will block if multiple transactions try to insert
  4. if insertion Failed then
  5. // somebody beat us at the race
  6. select the data for update
  7.  
  8. do processing
  9.  
  10. if data was changed then
  11. update the old or dummy data
  12. else
  13. rollback the whole transaction

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

解决方法

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

没有

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

最好的事情是桌子锁.

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

猜你在找的MsSQL相关文章