Oracle脏读

时间:2016-05-27 19:34:39

标签: php oracle isolation-level database-locking rowlocking

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

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

我的桌子上有一排像这样:

  • id:1
  • desc:' abc'

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

  • id:1
  • desc:' abc'

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

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

如何防止旧数据读取?

更新:

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

提前致谢。

2 个答案:

答案 0 :(得分:4)

你看到正常"读取已提交"行为。提交意味着"我已准备好让世界其他地方看到我的交易结果"。如果您没有提交它,那么它并不算作任何其他数据库会话。您要拨打的电话"旧数据"是最新提交的数据。

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

例如,可能有两个表,Orders表和Line Items表,其中Orders表具有所有行项的总计,当我添加行项时,我想更新它的订单相同的交易,以便总计反映新的订单项。我不希望其他用户能够看到对订单行或新订单项的更改,而不会看到其他更改,我希望两个更改一起显示,因此我在事务。

答案 1 :(得分:0)

有很好的理由只读取已提交的数据。一个简单的例子可能足以说服你,你认为你想要的东西实际上是个坏主意。

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

现在假设您坚持要查看未提交的更改。新部门已添加到“部门”,但在NOT NULL约束列中,它对于管理器具有NULL。你真的想看到吗?您可能会提出三种不同的方法,这会导致应用程序出现严重问题。

(我在这里跳过了细微之处,比如延迟约束,这就像上面那样的场景是可能的 - 这不是我的答案。)