1

我浏览了整个 Microsoft 站点以了解 SQL Server 2008 R2 中的隔离级别。但是,在采用之前,我想听取 SO 专家的建议。

我有一个基于 PHP 的网页,主要用作仪表板。用户(不超过 5 个)每天将上传批量数据(大约 40,000 行),大约 70 个用户将只能访问数据库。请注意,我为这 5 位用户设置了上传时间,但我想对任何数据丢失进行错误证明。帮我解决以下问题:

  • 我可以使用的最佳隔离级别是什么?
  • 默认的 READ COMMITTED 隔离对我有帮助吗?
  • 除了 TSQL 语句之外,还有没有办法通过 SSMS 为特定数据库设置隔离级别?(数据库的通用隔离)

70 个用户将有下载选项,如果所有或大多数用户同时尝试下载,数据库是否有可能损坏?我该如何避免同样的情况?

任何专家的建议......

问候, Yuvraj S

4

1 回答 1

6

隔离级别实际上与正在读取的数据上的共享锁保持多长时间有关。但正如 Lieven 已经提到的那样:这些不是为了防止数据库中的“损坏”——而是为了防止读者和作者相互妨碍。

首先:任何写操作(INSERT, UPDATE)将始终需要对该行的他锁,并且排他锁与其他任何内容都不兼容 - 所以如果要更新的给定行已经被锁定,任何UPDATE操作都必须等待 - 没办法围绕这个。

对于读取数据,SQL Server 取出共享锁- 隔离级别与持有这些锁的时间有关。

默认隔离级别 ( ) 意味着:SQL Server将READ COMMITTED尝试在一行上获取共享锁,如果成功,则读取该行的内容并立即再次释放该锁。所以锁只存在于被读取行的短暂时间内。共享锁与其他共享锁兼容,因此任意数量的读取器可以同时读取相同的行。然而,共享锁阻止了排他锁,因此共享锁主要阻止UPDATE了同一行。

然后还有READ UNCOMMITTED隔离级别——基本上没有锁;这意味着,它还可以读取当前正在更新和独占锁定的行-因此您可能会获得未提交的数据-最终甚至可能不会真正最终进入数据库的数据(如果更新它的事务被回滚) - 小心这个!

下一个级别是REPEATABLE READ,在这种情况下,一旦获得共享锁,就会一直持有,直到当前事务终止。这将锁定更多行并锁定更长的时间 - 读取是可重复的,因为您已读取的那些行被锁定以防止“背后”的更新。

最终级别是锁定SERIALIZABLE行的整个范围(由WHERE中的子句定义SELECT),直到当前事务终止。

更新:

不仅仅是下载部分(对我来说是次要的),我担心有 5 个用户试图同时更新一个数据库。

好吧,不用担心 - SQL Server肯定会毫无问题地处理这个问题!

如果这 5 个(甚至 50 个)并发用户正在更新不同的行 - 他们甚至不会注意到周围有其他人。更新将会发生,在这个过程中不会有任何数据受到伤害——一切都很好。

如果其中一些用户尝试更新同一行- 他们将被序列化。第一个将能够获得行上的排他锁,进行更新,释放锁,然后继续。现在第二个用户将得到它的机会 - 获得排他锁,更新数据,释放锁,继续。

当然:如果你不做任何事情,第二个用户的数据将简单地覆盖第一个更新。这就是为什么需要并发检查的原因。您应该检查数据在您读取数据和写入数据之间是否发生了变化;如果它已更改,则意味着其他人同时已对其进行了更新->您需要考虑针对这种情况的并发冲突解决策略(但这本身就是另一个问题……)

于 2013-02-13T06:30:22.477 回答