我碰巧使用的是innodb,read-committed。
我的简单问题是,这与事务相关:
我有一个表(TreeNodeId),其中包含一组4个不同的节点键,这些节点键代表了我系统中与网页的可用路径相关的所有现有节点。
即使这个查询获取了10,000行,它也会在内部保持一致吗?数据库查询集有没有可能获得前100行,然后让其他一些并发事务提交新的或已删除的行,从而导致剩余的结果不一致?
安迪
发布于 2013-01-20 00:15:20
如果您的隔离级别是读取“提交”,它将只返回已由事务日志“提交”的结果。因此,如果您在该时间点启动一个隔离级别为“committed”的查询,sql事务日志将只向您提供已提交到其日志中的事务。如果在选择过程中有人发布了记录,那么这些记录在该时间点将被视为“未提交”,直到他们结束操作并被“提交”。但是,即使您将级别更改为“未提交”,您也不应该获取数据,因为它处于中流状态,您应该根据事务日志获取引擎在开始操作时可用的数据。
Committed与uncommitted将在选择时获取系统中的记录,这些记录基于您的选择。因此,假设我有3,000,000条记录和200,000条插入的记录,但他们一次提交一条记录,只有100,000条记录已经提交,100,000条记录知道日志中的操作,但尚未提交。
承诺会给我3,100,000,未承诺会给3,200,000。然而,有不同的思想流派,我昨天刚刚开始与某人讨论这个问题……Uncommitted将给出未提交的结果,并被称为“脏读”,因为您正在读取尚未设置的日志(您是叛逆者)。你在说:“嘿,数据库,我不在乎你收到的是什么,我现在就想要它。”当你说提交时,你是在说:“数据库我只想要合格的数据,如果有些东西没有最终确定,我就不想要它。”
每种方式的优点:
老实说,在我的讨论中,我倾向于不承诺,而另一个人倾向于承诺。我认为获取脏数据要比停止生产插入更容易接受。他们认为幻影读取和其他实例更糟糕。这是一种观点,SQL系统是围绕inserts和selects而设计的,但很少能在不减少另一项的影响的情况下以极快的速度完成这两项工作。如果您想要准确的报告,我的答案是执行夜间备份、SSIS包、二进制收集或隔离级别的类似操作,如快照或提交,并将数据放在某个位置。让数据以一种我们知道它是最终确定的方式进行设置,并且它被锁定,这样它以后就不会被更改并报告出来。不要在生产数据过热时报告,一定要告诉每个人都要这样做。告诉人们实时报告执行插入和更新的实时数据本身就是一种糟糕的做法。
如果你是一家只有5到10个人使用数据库的小商店,这会不会伤害到你,可能不会。如果你稍微大一点,有50个人访问同一个数据库,这会不会有什么影响,但它大约是100 of,而且是半事务性的,因为你在一天中获得了少量的数据。可能还是不会。如果你有200个人,多个服务器和数据库,以及一个主要的事务数据库大脑来存储所有数据的组合,这会有什么影响吗?当然,如果主生产数据库的主要目的是存储数据,则不要从具有密集操作的主生产数据库中读取数据。
编辑到来自真实世界示例的更多要点:
这就是为什么通常在我不使用表变量(declare @Table table)的大多数操作的顶部,我会设置这个:"set transaction isolation level read uncommitted“。我会在每次查询时都密集地使用它吗?哈哈,我希望不是。事实上,完全公开,从这一点上可能永远不会对我有帮助,因为我用临时表隔离了我的数据很多,用于巨大的事务报告。但我不会被其他人指责,我有一个长时间运行的事务阻塞了他们的插入。你还会看到很多人这样做:"select * from table ( nolock )“我通常会给较少的查询设计者这样的代码,因为它将nolock提示嵌入到查询中。如果我告诉每个人这样做,他们就会制定政策。
你不必这样做,事实上,有些人可能会跟随我,声称这是错误的,并张贴他们的立场。我这么做主要是为了保护生产,任何人告诉我这是错的,我想知道为什么他们喜欢在生产中锁定表并报告它们,而不是首先实时获取或更新数据。我会很难去找一个经理说:“你知道你等待发布200万条记录的大帐户,并且知道它完成的实例。嗯,大厅下面的John真的很想运行这个查询,这个查询需要一个小时才能运行,因为它的设计很草率。他选择使用提交,并在一些表上执行插入操作,所以我们偶尔会遇到锁。好吧,我认为他得到报告比我们得到业务更重要。”我想知道经理会对我说些什么?
https://stackoverflow.com/questions/14415686
复制相似问题