对于我的问题,My answer Is a half-written values reading prevented when SELECT WITH (NOLOCK) hint?引用了一个脚本来说明如何捕获SQL Server中部分更新的值的非原子读取(选择)。
这种非原子(部分更新、插入、删除)的值读取问题是SQL Server特有的吗?
是否可以在其他DBMS-es中使用?
更新:
不久前,我认为READ UNCOMMITTED transaction隔离级别(也是通过SQL Server中的(NOLOCK)提示实现的)允许读取(从其他事务中)未提交(或已提交,如果尚未更改)值,但不允许部分修改(部分更新、部分插入、部分删除)值。
Update2:
前两个答案将讨论转移到了攻击由ANSI/ISO SQL-92规范指定的读取未提交(隔离级别)现象。
这个问题不是关于这个的。
是值的非原子性(不是行!)是否符合读取未提交和脏读取的要求?
我认为未提交读取确实意味着读取未提交行的全部行,但不意味着读取部分修改的值。
“脏读”的定义是否包括值修改非原子性的可能性?
这是一个bug还是被设计出来的?
还是由美国国家标准协会SQL92定义的“脏读”?我相信“脏读”确实包括原子读取未提交的行,但非原子修改的值...
发布于 2010-11-27 21:25:43
是否可以在其他数据库管理系统中使用?
据我所知,在使用非事务性引擎时,唯一允许读取未提交的数据库是DB2、Informix和MySQL。
发布于 2010-11-28 01:16:21
如果原子声明实际上不是原子的,那么所有的地狱都会崩溃。
我可以为MSSQL回答这个问题--所有的单条语句都是原子的,“脏读”指的是在提交/回滚TX后读取可能不存在的“幻象行”的可能性。
发布于 2010-11-28 07:37:36
如果后者的实现依赖于锁定,那么原子性和读提交之间是有区别的。
考虑事务A和B。事务A是状态为“pending”的所有记录的单一SELECT (可能是对非常大的表进行完全扫描,因此需要几分钟时间)。
At 3:01 transaction A reads record R1 in the database and sees its status is 'New' so doesn't return it or lock it.
At 3:02 transaction B updates record R1 from 'New' to 'Pending' and record R2000 from 'New' to 'Pending' (single statement)
At 3:03 transaction B commits
At 3:04 transaction A reads record R2000, sees it is 'Pending' and committed and returns it (and locks it).在这种情况下,事务A中的select只看到了事务B的一部分,这违反了原子性。不过,从技术上讲,select只返回已提交的记录。
依赖于锁定读取的数据库会受到这个问题的困扰,因为唯一的解决方案是锁定正在读取的整个表,这样任何人都不能更新其中的任何记录。这使得它对于任何并发活动来说都是不切实际的。
在实践中,大多数OLTP应用程序在非常小的数据量(相对于数据库大小)上具有非常快速的事务操作,并且并发操作往往会命中不同的数据“切片”,因此这种情况很少发生。即使它真的发生了,也不一定会导致明显的问题,即使发生了,它们也很难重现,修复它们需要一个全新的体系结构。简而言之,尽管这是一个理论上的问题,但在实践中往往不值得担心。
也就是说,架构师应该意识到潜在的问题,能够评估特定应用程序的风险,并确定替代方案。
这就是为什么SQL Server added non-locking consistent reads in 2005。
https://stackoverflow.com/questions/4291622
复制相似问题