当前位置: 首页 > 面试题库 >

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

范麒
2023-03-14
问题内容

我们在应用程序中有一些持久性数据,这些数据是从服务器查询然后存储在数据库中的,因此我们可以跟踪其他信息。因为我们不想查询何时在内存中使用对象,select for update所以我们这样做是为了阻止其他想要获取相同数据的线程。

我不确定如何select for update处理不存在的行。如果该行不存在,并且另一个线程尝试select for update在同一行上执行另一个操作,那么该线程是否会被阻塞,直到另一个事务完成,或者它还会得到一个空结果集?如果它只得到一个空结果集,是否有办法使其阻塞,例如立即插入丢失的行?

编辑:

因为有一个说法,我们可能会锁定太多,这里有一些关于我们案例中具体用法的更多细节。在简化的伪代码中,我们的程序流程如下所示:

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

此代码在多线程中运行,并且从队列中获取的数据可能与数据库中的同一行有关(因此为锁)。但是,如果多个线程正在使用需要同一行的数据,则需要对这些线程进行排序(顺序无关紧要)。但是,如果不存在该行,则此排序失败,因为我们没有得到锁。

编辑:

目前,我有以下解决方案,对我来说这似乎是一个丑陋的hack。

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

我既不能百分百地确定这确实可以解决问题,也不能保证这种解决方案看起来不错。因此,如果有人必须提供更多可用的功能,那就太好了。


问题答案:

我不确定如何选择更新来处理不存在的行。

没有。

如果您知道新行的独特之处,那么最好的办法就是使用咨询锁。(如果需要,请使用hashtext(),并使用表的oid对其进行锁定。)

下一个最好的事情是表锁。

话虽这么说,但您的问题却听起来像是您的锁定方式超出了您应有的程度。仅在实际需要时才锁定行,即写操作。



 类似资料:
  • 问题内容: 有没有简单的方法来选择更新的行? 我试图每次读取行时都存储时间戳,以便能够删除长时间未读取的数据。 首先,我首先尝试执行查询,甚至发现有点慢但是简单的解决方案,例如 但我仍然想找到一种正常的方法来做到这一点。 我还认为先更新时间然后选择更新的行应该容易得多,但是即使如此,我也没有找到任何东西 问题答案: 声明该列,如下所示: 然后,每当更新一行时,该列就会自动更新。 更新: 我认为没有

  • 问题内容: 我认为我要沿着这条路走正确的路…请忍受,因为我的SQL并不是最出色的 我试图查询数据库以从一个表中选择所有单元格中某些单元格不存在的所有内容。那没有多大意义,但我希望这段代码会 因此,基本上我有一张桌子,上面列出了员工及其详细信息。然后是另一个表,其中包含一些其他详细信息,包括其名称。在eotm_dyn表中没有名称的地方,这意味着它们没有条目,我想确切地知道它们是谁,或者换句话说,确切

  • 问题内容: 我有两个postgresql表: 我想获取其中没有一行的每个IP地址。 我尝试了此查询,但它引发了语法错误。 我也想知道此查询(进行调整以使其工作)是否是为此目的性能最佳的查询。 问题答案: 基本上有4种技术可以完成此任务,所有这些技术都是标准SQL。 在Postgres中通常最快。 [](https://www.postgresql.org/docs/current/queries-

  • 我有两个postgresql表: 我想从登录日志中获取每个IP地址,它在IP\U位置中没有一行 我尝试了此查询,但它引发了语法错误。 我还想知道这个查询(通过调整使其工作)是否是用于此目的的性能最好的查询。

  • 问题内容: 我正在尝试使用相同的表查询更新行。语境: 我想:对于每一行;如果 TEXT为NULL ; 使用具有相同ID且LANG =’EN’的行的TEXT值更新它。 做这样的事情的SQL请求是什么? 问题答案: 您没有指定数据库。以下是标准SQL: 如果出现重复,则应执行以下操作: 编辑: 当然,并非所有数据库都支持所有ANSI标准功能。在MySQL中,您可以改用:

  • 问题内容: 根据MySql文档,MySql支持多重粒度锁定(MGL)。 打开终端1: //连接到mysql 离开它打开并打开终端2: //连接到mysql 尽管要检索的行很多,但T2等待直到t1完成。 情况2 保持端子1不变,现在位于端子2中: 但是,为什么在情况1中,T2等待T1锁定的同一行集? 这是否意味着无限制的选择查询(即使使用limint参数。我也尝试了不同的范围)阻塞了整个表? 有什么