Php 甲骨文脏读

Php 甲骨文脏读,php,oracle,isolation-level,database-locking,rowlocking,Php,Oracle,Isolation Level,Database Locking,Rowlocking,我刚刚使用Oracle database 11g 我正在使用SQLDeveloper测试表锁和行锁 我的表格中有一行是这样的: 身份证号码:1 描述:“abc” 我在没有提交的情况下进行了更新,将字段desc更改为“zxc”。在另一个会话中,我进行了一次选择,返回了旧记录: 身份证号码:1 描述:“abc” 我想它会给我一个错误或其他东西,因为我不想看到旧数据 最后,当我在另一个会话中提交时,我在第二个会话中再次执行查询,并返回提交的数据 如何防止读取旧数据 更新: 我读过sql SELECT

我刚刚使用Oracle database 11g

我正在使用SQLDeveloper测试表锁和行锁

我的表格中有一行是这样的:

身份证号码:1 描述:“abc” 我在没有提交的情况下进行了更新,将字段desc更改为“zxc”。在另一个会话中,我进行了一次选择,返回了旧记录:

身份证号码:1 描述:“abc” 我想它会给我一个错误或其他东西,因为我不想看到旧数据

最后,当我在另一个会话中提交时,我在第二个会话中再次执行查询,并返回提交的数据

如何防止读取旧数据

更新:

我读过sql SELECT FOR UPDATE,它阻止获取未提交的行,但例如有人告诉我有关银行的信息,所以我不确定这种方法是否具有良好的性能,其他问题是关于未提交时的连接丢失。也许我需要使用一个函数或PLSQL来最小化丢失的连接,实际上我使用的是一个PHP脚本Laravel框架


提前感谢。

您看到了正常的阅读承诺行为。提交意味着我准备好让世界其他地方看到我事务的结果。如果您没有提交它,那么对于任何其他数据库会话,它都不算在那里。您所称的旧数据是最新提交的数据

糟糕的是,如果在提交更新之前就可以看到更新,这就是readuncommitted隔离级别。事务的存在使您可以原子地对数据库进行更改,以便查询查看一致的状态,而不是半成品的更改


例如,可能有两个表,Orders表和Line Items表,其中Orders表包含所有行项目的合计,当我添加行项目时,我希望在同一事务中更新该行项目的订单,以便合计反映新的行项目。我不希望其他用户能够在看不到其他更改的情况下看到订单行或新行项目的更改,我希望这两个更改同时可见,因此我在事务中进行更改。

有很好的理由只读取提交的数据。一个简单的例子就足以让你相信你认为你想要的其实是个坏主意

仅在事务结束时提交(而不是在每次行更新或插入后提交)的一个原因是为了方便输入具有引用完整性约束的数据,其中仅在事务结束时检查约束。假设已经创建了一个新部门,并且它有一个经理。您可以在departments表中创建新行,但这需要一个manager值。您可以在employees表中创建经理行,但这需要一个部门。你先做哪一个?答案-这无关紧要,因为完整性只在事务插入到两个表的末尾检查

现在假设您坚持要看到未提交的更改。新部门已添加到部门中,但在受NOT NULL约束的列中,经理的新部门为NULL。你真的想看吗?您可能会想到三种不同的方法,这会在应用程序中造成严重问题


我在这里跳过了一些微妙之处,比如延迟约束,这就是上述场景的可能性——这不是我回答的重点。

你可能想读一下:这就像编辑共享文档一样。您真的希望其他用户在单击“保存”之前看到您所做的更改吗?数据库提交类似于保存文档。只有在您明确声明通过提交批准更改后,更改才会对世界可见。您可以更改隔离级别read uncommitted来更改该行为,但是对于Oracle这样的数据库,我想不出一个好的理由来这样做。我希望sql会给我一个错误。仅在提交或rollback@user2876735想象一下,这在银行交易环境中是如何工作的。插入一行时,所有操作都必须停止。系统不知道哪个客户端的帐户将受到影响,因此在提交或回滚之前,所有操作都必须停止。在那样的世界里,几乎不可能有什么工作。