2013-02-13 129 views
1

我已经通过整个Microsoft站点了解SQL Server 2008 R2中的隔离级别。然而,在采纳之前,我想向SO的专家提出建议。SQL Server 2008 R2中的隔离级别

我有一个基于PHP的网页主要用作仪表板。用户(不超过5个)每天将上传大量数据(大约40,000行),大约70个用户只准备访问数据库。请注意,我已经为这5个用户上传了固定的时间表,但是我想对相同的数据丢失进行证明。请帮助我解决以下问题:

  • 什么是我可以使用的最佳隔离级别?
  • 默认的READ COMMITTED隔离会帮助我吗?
  • 还有一种方法可以通过SSMS为TSQL语句以外的特定数据库设置隔离级别吗? (为一个数据库通用隔离)

70用户将有下载选项,是有一个机会,如果所有或大部分试图在同一时间下载该数据库将遭到损坏?我如何避免相同?

专家的任何建议....

问候, 俞拉吉小号

+4

隔离级别为**不是关于**屏蔽你的数据损坏,而是关于**锁定数据**在变化和**阅读数据**使用选择*(承诺,uncommited,脏,幻影)*。对于大多数意图和目的,默认隔离级别就足够了。 – 2013-02-13 06:23:11

+1

btw:如果所有尝试同时下载,则不必担心数据库遭到破坏。这就是[ACID](http://en.wikipedia.org/wiki/ACID#Consistency)中的一致性*(和耐久性)*的保证。 – 2013-02-13 06:31:50

回答

6

隔离级别是真正关心共享多久的数据是读锁被保留。但正如列文已经提到的那样:那些关于防止数据库中的“腐败”的是NOT--这些是关于防止读者和作者进入对方的方式。

第一项:任何写操作(INSERTUPDATE)将总是需要在该行的独家锁和排它锁不与任何其他兼容 - 所以,如果要更新的给定行已锁定,任何UPDATE操作将不得不等待 - 没有办法解决这个问题。

对于读取数据,SQL Server会出共享锁 - 和隔离级别是如何长的持有。

默认隔离级别(READ COMMITTED)表示:SQL Server将尝试获取行上的共享锁,如果成功,读取行的内容,并再次释放锁的时候了。所以锁只存在于被读取行的短暂时间内。共享锁与其他共享锁兼容,所以任何数量的读者可以同时读取相同的行。然而,共享锁会阻止排它锁,所以共享锁主要阻止相同行上的UPDATE

然后还有READ UNCOMMITTED隔离级别 - 基本上不会锁定;这意味着它还可以读取当前正在更新并且被独占锁定的行 - 这样您可能会得到未提交的数据 - 最终可能不会真正在数据库中结束的数据(如果事务将其更新回滚) - 小心这个!

下一级是REPEATABLE READ,在这种情况下,一旦获取共享锁,将保留到当前事务终止。这会锁定更多行并延长一段时间 - 读取是可重复的,因为您已经读取的行被“锁定在后面”的更新锁定。

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

更新:比下载的部分(二次对我来说)我担心的是5个用户试图在同一时间更新一个数据库

更多。

好了,不要担心 - SQL Server将肯定处理这个没有任何麻烦!

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

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

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

+0

好帖子。您忘记了READ UNCOMMITTED隔离级别,足以满足OP的需要;) – danihp 2013-02-13 06:41:26

+0

谢谢大家对此主题的建议和知识。不止是下载部分(对我来说是次要的),我担心有5个用户试图同时更新一个数据库。 – 2013-02-13 06:42:44

+2

@ user1926468:对于SQL Server,有五个并发用户是**没有** - 它很容易**确保没有数据可以被两个事务一次更新它们破坏。 – 2013-02-13 06:43:48