隔离级别实际上与正在读取的数据上的共享锁保持多长时间有关。但正如 Lieven 已经提到的那样:这些不是为了防止数据库中的“损坏”——而是为了防止读者和作者相互妨碍。
首先:任何写操作(INSERT
, UPDATE
)将始终需要对该行的排他锁,并且排他锁与其他任何内容都不兼容 - 所以如果要更新的给定行已经被锁定,任何UPDATE
操作都必须等待 - 没办法围绕这个。
对于读取数据,SQL Server 取出共享锁- 隔离级别与持有这些锁的时间有关。
默认隔离级别 ( ) 意味着:SQL Server将READ COMMITTED
尝试在一行上获取共享锁,如果成功,则读取该行的内容并立即再次释放该锁。所以锁只存在于被读取行的短暂时间内。共享锁与其他共享锁兼容,因此任意数量的读取器可以同时读取相同的行。然而,共享锁阻止了排他锁,因此共享锁主要阻止UPDATE
了同一行。
然后还有READ UNCOMMITTED
隔离级别——基本上没有锁;这意味着,它还可以读取当前正在更新和独占锁定的行-因此您可能会获得未提交的数据-最终甚至可能不会真正最终进入数据库的数据(如果更新它的事务被回滚) - 小心这个!
下一个级别是REPEATABLE READ
,在这种情况下,一旦获得共享锁,就会一直持有,直到当前事务终止。这将锁定更多行并锁定更长的时间 - 读取是可重复的,因为您已读取的那些行被锁定以防止“背后”的更新。
最终级别是锁定SERIALIZABLE
行的整个范围(由WHERE
中的子句定义SELECT
),直到当前事务终止。
更新:
不仅仅是下载部分(对我来说是次要的),我担心有 5 个用户试图同时更新一个数据库。
好吧,不用担心 - SQL Server肯定会毫无问题地处理这个问题!
如果这 5 个(甚至 50 个)并发用户正在更新不同的行 - 他们甚至不会注意到周围有其他人。更新将会发生,在这个过程中不会有任何数据受到伤害——一切都很好。
如果其中一些用户尝试更新同一行- 他们将被序列化。第一个将能够获得行上的排他锁,进行更新,释放锁,然后继续。现在第二个用户将得到它的机会 - 获得排他锁,更新数据,释放锁,继续。
当然:如果你不做任何事情,第二个用户的数据将简单地覆盖第一个更新。这就是为什么需要并发检查的原因。您应该检查数据在您读取数据和写入数据之间是否发生了变化;如果它已更改,则意味着其他人同时已对其进行了更新->您需要考虑针对这种情况的并发冲突解决策略(但这本身就是另一个问题……)