回答

收藏

在不存在的行上有选择更新块

技术问答 技术问答 262 人阅读 | 0 人回复 | 2023-09-14

我们从服务器中查询并存储在数据库中,因此我们可以跟踪其他信息。因为我们不想查询什么时候在内存中使用对象,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尽管如此,但你的问题听起来像是你的锁定方式超出了你应有的程度。只有在实际需要时才能锁定行,即写作操作。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则