为键在列表中的行提交读取(读取是原子的吗?)



我碰巧正在使用innodb,读取已提交。

我的简单问题是,这与交易有关:

我有一个表(TreeNodeId),其中包含一组4个不同的节点密钥,它们表示我的系统中与网页可用路径相关的所有现有节点。每个键表示数据库中的一个项,表中的每一行表示使用项的各种组合。

在事务开始时,根据更改的项目,我对TreeNodeId中的所有行进行一次查询,这些行反映了我的一个或两个项目的一些现有组合。

即使这个查询获取了10000行,它在内部是否会保持一致?数据库查询集是否可以获取前100行,然后其他同时进行的事务是否可以提交新的或已删除的行,从而导致重映射结果不一致?

Andy

如果隔离级别被读取为"提交",它将只返回事务日志已"提交"的结果。因此,如果您在该时间点启动了一个处于隔离级别"提交"的查询,sql事务日志将只向您提供已提交的事务。如果在选择过程中有人发布记录,则他们将在该时间点被视为"未提交",直到他们结束操作并被"提交"。但是,即使您将级别更改为"未提交",也不应获取处于流中的数据,您应该根据事务日志获取在开始操作时引擎可用的数据。

Committed和uncommitted将在选择时获得系统中基于您的选择的记录。所以,如果我说3000000条记录和200000条记录插入,但他们一次提交一条,只有100000条已经提交,100000条知道日志中的操作,但还没有提交。

承诺会给我3100000,非承诺会给320万。然而,也有一些学派,我昨天刚刚和某人讨论了这个问题。。。。未提交会给你未提交的结果,被称为"脏读取",因为你正在读取尚未设置的日志(你反抗)。你说的是"嘿,数据库,我不在乎你收到的是什么,已经定稿了,我现在就想要。"当你说"提交"时,你说的就是:"数据库,我只想要合格的数据,如果没有定稿,我就不想要。">

各有优势:

  1. 未承诺您不会锁定任何内容。你基本上是在对系统说:"不要锁定任何东西,让我自由地浏览系统,得到那里的东西,我不在乎你是否更改了什么。我希望它在操作时出现。"如果你执行此操作时有东西试图插入或更新,它不会锁定它。

  2. Committed不会锁定除正在提交的内容之外的任何内容,直到您的操作完成。您可以放心地知道您返回的数据已最终确定,但您会面临阻止交易试图插入或发布的风险。你基本上是在告诉数据库:"等我完成后,再继续对我正在访问的表进行提交。我需要我的数据准确无误,所以在我完成之前不要干涉"。这可能会在数据对从中收集的表执行读取时锁定数据。这并不常见,因为大多数选择都是近乎即时的,但在基于每秒发布数千条记录的事务性大型系统上,这是一个大问题。

老实说,在我的讨论中,我倾向于不承诺,而另一个人则倾向于承诺。我认为获取脏数据比停止生产插入要容易得多。他们认为幻影阅读和其他情况更糟。这是一种观点,SQL系统是围绕插入和选择来设计的,但很少能在不从另一个中抽离一点的情况下以极快的速度同时完成这两个操作。如果您想要准确的报告,我的答案是进行夜间备份、SSIS包、二进制集合或类似的隔离级别(如快照或提交),并将数据放在某个地方。让数据以一种我们知道它已经最终确定并被锁定的方式设置,这样以后就不会更改它并报告它。不要急于报告生产数据,并明确要求每个人都这样做。告诉人们报告实时执行插入和更新的实时数据本身就是一种糟糕的做法。

如果你是一家只有5到10个人在使用数据库的小型夫妻店,可能不会,这会有伤害吗。如果你稍微大一点,有50个人访问同一个数据库,但这大约是100场演出,而且是半事务性的,因为你在一天中会得到涓涓细流的数据,这会不会很痛苦。可能仍然没有。如果你有200个人、多个服务器和数据库,以及一个主要的事务数据库大脑来存储所有数据的组合,会不会很痛苦。如果主要目的是获取要存储的数据,那么绝对不要从具有密集操作的主生产数据库中读取。

编辑到现实世界的进一步点示例:

这就是为什么通常在大多数不使用表变量的操作(declare@Tabletable)的顶部,我设置为:"设置事务隔离级别read uncommitted"。我会在每次询问时都强烈使用它吗?哈哈,我希望不会。事实上,从现在起,它可能永远不会对我有帮助,因为我用临时表隔离了我的数据,用于大量的事务报告。但我不会被其他人吼——我有一个长期的事务阻止了他们的插入。你还会看到很多人这样做:"从表中选择*(nolock)"我通常会把这样的代码提供给较小的查询设计器,因为它在查询中嵌入了nolock提示。如果我告诉每个人都这样做,他们就会制定政策。

你不必这样做,事实上,有些人可能会追随我,声称这是错误的,并发表他们的观点。我这样做主要是为了保护生产,任何告诉我这是错误的人,我想知道他们为什么喜欢在生产中锁定表并报告它们,而不是首先实时输入或更新它们的数据。我很难去找经理说:"你知道那个巨大的账户,你一直在等待发布200万条记录,并知道它已经完成的实例。大厅里的约翰真的很想运行这个需要一个小时才能运行的查询,因为它设计得很草率。他选择了使用committed,并且正在点击一些表进行插入,所以我们偶尔会被锁定。好吧,我认为他得到他的报告比我们得到报告更重要。"et业务。"我想知道经理会告诉我什么?

最新更新