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

是否使用嵌套的select原子操作进行更新?

南宫阳冰
2023-03-14
问题内容

我需要先选择(假设)数据库中的10000行并将其返回。可能有更多的客户端一次执行此操作。我想出了这个查询:

update v set v.batch_Id = :batchId 
    from tblRedir v 
    inner join (
        select top 10000 id 
            from tblRedir
            where batch_Id is null 
            order by Date asc
    ) v2 on v.id=v2.id

这是一个由更新和嵌套选择组成的操作。这两个查询都在同一表(tblRedir)上工作。这个想法是,这些行首先用唯一的batchId进行标记,然后通过进行返回

select * from tblRedir where batch_id = :batchId

(对于每个此更新,batchid是唯一的标识符(例如,时间戳或guid))

我的问题:

我认为 使用嵌套选择进行 的操作 更新 是原子的-这意味着每个客户端都将接收自己的唯一数据集(没有其他客户端会接收其数据的子集)。

但是,看来我是错的-在某些情况下,有些客户端没有接收到数据,因为可能它们首先 执行了选择, 然后都
执行了更新(因此第一个客户端没有标记的行)。

此操作是否为原子操作?

我使用Sql Server2005。查询是通过NHibernate这样运行的

session.CreateSQLQuery('update....')

问题答案:

SELECT在读取的行上放置共享锁,然后可以在READ COMMITED隔离模式下解除共享锁。

UPDATE将更新锁升级为排他锁。直到交易结束它们才被解除。

您应将锁放置后立即保留。

您可以通过设置事务隔离级别来做到这一点,该级别REPEATABLE READ将保留共享锁直到事务结束,并防止UPDATE部分锁定这些行。

或者,您可以按以下方式重写查询:

WITH    q AS
        (
        SELECT  TOP 10000 *
        FROM    mytable WITH (ROWLOCK, READPAST)
        WHERE   batch_id IS NULL
        ORDER BY
                date
        )
UPDATE  q
SET     batch_id = @myid

,这只会跳过锁定的行。



 类似资料:
  • 当我们使用一个内置队列,如ConprestLinkedQueue甚至一些BlockingQueue时,单个调用是原子的,并保证是线程安全的。但是当对API的5次调用中,有4次调用是单个调用时,但有一次调用的形式是: 这个调用需要在一个同步块中,因为这个操作是非原子的。但是引入这个调用不也意味着从此以后对这个队列的所有访问,不管是读还是写,都应该同步吗? 如果是,我可以假设一旦代码中出现单个非原子调

  • 本文向大家介绍C#中使用Interlocked进行原子操作的技巧,包括了C#中使用Interlocked进行原子操作的技巧的使用技巧和注意事项,需要的朋友参考一下 什么是原子操作? 原子(atom)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为”不可被中断的一个或一系列操作” 。在C#中有多个线程同时对某个变量进行操作的时候,我们应该使用原子操作,防止多线

  • 我在创建使用嵌套查询或使用联接更新实体CommitteeMembership的HQL时遇到问题,我首先尝试了以下查询: 但生成的SQL错误如下: 在“交叉连接”之后没有任何this使Hibernate抛出SQLGrammarException 之后,我将查询更改为使用子查询: 现在Hibernate投球 任何人都知道我如何在HQL中编写此更新查询??

  • 问题内容: 我遇到了以下SYBASE SQL: 该SQL的结果是 这看起来像是将HAVING条件应用于行而不是组。有人可以帮我指出描述这种情况的地方是Sybase 15.5文档吗?我所看到的只是“在团队中运作”。我在文档中看到的最接近的是: hading子句可以包括不在选择列表中且不在group by子句中的列或表达式。 (从这里引用)。 但是,他们没有完全解释当您这样做时会发生什么。 问题答案:

  • 问题内容: 我想知道单个文件的写入是否原子完成,从而对同一文件的write(“ bla bla”)和随后的write(“ herp derp”)永远不会导致交织,例如“ bla herp bla derp ”。假设这些写操作发生在不同的进程或线程中,什么决定了哪个先完成? 另外,read()是否始终以完全完成的所有先前写入的状态返回反映文件的数据(无论该数据实际上是否已写入磁盘)?例如,在writ

  • 问题内容: 为什么以下SQL语句不起作用? 它产生此错误: 查询输入必须至少包含一个表或查询。 单个语句有效。 问题答案: Access SQL语句不会让您对以下其中一项使用子查询 按照Piotr的建议,切换到语句即可。 或者,您可以在语句中使用Access Domain Aggregate函数而不是子查询: