2

我是使用 Oracle 数据库 11g 的新手。

我正在使用 SQL Developer 测试表和行锁。

我的表中有这样的一行:

  • 编号:1
  • 描述:'abc'

我进行了更新而没有提交将字段更改desc'zxc'. 在另一个会话中,我做了一个返回旧记录的选择:

  • 编号:1
  • 描述:'abc'

我在想它会给我一个错误或其他东西,因为我不想看到旧数据。

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

如何防止读取旧数据?

更新:

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

提前致谢。

4

2 回答 2

4

您会看到正常的“已提交读”行为。提交意味着“我准备好让世界其他地方看到我的交易结果”。如果您不提交它,那么对于任何其他数据库会话,它都不算存在。您所说的“旧数据”是最新提交的数据。

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

例如,可能有两个表,一个 Orders 表和一个 Line Items 表,其中 Orders 表包含所有行项目的总计,当我添加一个行项目时,我想在同一个事务中更新它的 Order以便总数反映新的行项目。我不希望其他用户能够看到 Orders 行或新行项目的更改而没有看到其他更改,我希望这两个更改一起可见,因此我在事务中进行更改。

于 2016-05-27T19:43:22.557 回答
0

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

仅在事务结束时提交而不是在每次更新或插入后提交的一个原因是为了便于输入具有参照完整性约束的数据,其中仅在事务结束时检查约束。假设已经创建了一个新部门,并且它有一个经理。您在“departments”表中创建了一个新行,但这需要一个 manager 值。您在“员工”表中创建“经理”行,但这需要一个部门。你先做哪个?答案 - 没关系,因为仅在事务结束时检查完整性(插入两个表)。

现在想象一下,您坚持要查看未提交的更改。新部门已添加到“部门”,但在 NOT NULL 约束列中,经理为 NULL。你真的想看到吗?您可能会想出三种不同的方式来解决您的应用程序中的严重问题。

(我在这里跳过了诸如延迟约束之类的微妙之处,这就是上述场景的可能方式——这不是我回答的重点。)

于 2016-05-27T20:03:35.567 回答