【问题标题】:Why does SQL*Plus commit on exit?为什么 SQL*Plus 在退出时提交?
【发布时间】:2010-11-24 23:34:37
【问题描述】:

当然这应该与会话终止并导致回滚相同?在我看来,这似乎是最非 Oracle 的事情。当我发现它这样做时,我真的很震惊

更重要的是——如果 Oracle 将其更改为退出时回滚,会有人反对吗?

【问题讨论】:

  • 关于更改 - 如果更改默认行为,肯定会有数千个脚本会中断。如果它是一个可配置的选项(以某种方式),也许可以更改默认值,但不是这样。这就是已经部署超过 1 分钟的软件的生命 - 你不能轻易改变决定。
  • 我认为它很容易改变。我遇到了 SQL*Plus 无法自动提交的问题,这确实让人们感到困惑,或者可能是因为应用程序仍处于打开状态,它还没有提交。
  • 在新的 11gR2 SQL*Plus 上作为一个选项提供

标签: oracle sqlplus


【解决方案1】:

你得问问甲骨文!

我必须承认,当我第一次发现这一点时,我感到很惊讶,因为您认为它会采取更保守的方法,即进行 ROLLBACK。

我只能猜测 COMMIT 被认为是最有可能/默认的操作,也许这就是 SQL*Plus 这样做的原因?

【讨论】:

  • 但是 ROLLBACK 肯定是最安全的。 Oracle 中的其他所有内容 似乎都是为了保护数据而设置的
  • 我同意,它认为 SQL*Plus 的行为也很奇怪!
【解决方案2】:

这是甲骨文的设计决策,可能是 20 多年前做出的。这不是我会使用的设计。请注意,它似乎是 SQL*Plus 的属性,而不是底层 OCI 的属性。

如果会话突然终止,AFAIK,会话将回滚,如您所料。因此,例如,如果有人向 SQLPlus 发送 SIGKILL,则应该回滚会话的事务。但是,如果 SQLPlus 会话正常终止(EOF 或退出命令),那么 SQL*Plus 以其无限的智慧决定提交您迄今为止所做的任何事情。

至于为什么 - 我有一个理论。在 SQL 标准数据库中,您始终处于事务中,即使您执行的唯一操作是 SELECT 语句。如果您不提交,那么您所做的任何更改都会回滚。很容易忘记在脚本操作的末尾添加提交,因此将其设置为默认行为可以减少有人运行脚本更改数据库然后运行第二个脚本以查看更改是否正确生效的次数。其他 DBMS 使用“自动提交”等模式消除了对这种情况的需求,其中每条语句都是一个独立的事务,在完成时自动提交。这是一种有用的操作模式。其他系统提供了一种模式,您处于自动提交状态,直到您运行显式的 BEGIN WORK 语句,因此(当然)您处于事务中,直到相应的 COMMIT 或 ROLLBACK。我被 'MODE ANSI' 数据库所吸引,没有足够频繁地提交以确保我在重要时提交,但我使用的软件(不是 Oracle)仍然回滚未提交的工作,而不是默默地为你提交 - 我会如果将其更改为其他方式,则不高兴。 (我想一个可配置的默认值可能没问题;我仍然认为未提交的回滚是更好的默认值,因为它对不知情的人来说是一种麻烦;意外损坏数据库的危险较小,这对我来说至关重要。)

(适当通知:这是来自为另一个 DBMS 供应商工作的人提供的二手信息。然而,据我所知,它是准确的,并且基于一段时间内积累的信息十多年,并在各种论坛上提出相关问题后。)

【讨论】:

  • 感谢乔纳森的评论 - 我在等着看看是否有人认为提交实际上是个好主意!
【解决方案3】:

我认为提交是个好主意,我同意 Justin 和 Billy 在此线程中所写的内容:http://forums.oracle.com/forums/thread.jspa?messageID=3611345&#3611345

问候, 抢。

【讨论】:

  • 我不同意 Justin 和 Billy 在线程中的观点——但这并不能使提交成为一个好主意。退出时提交似乎表明在退出 SQL*Plus 之前不显式提交您的工作是一种预期行为,好像这是一件好事。
  • 每个脚本都应该明确地处理事务,而不依赖于某些客户端的默认行为。这就是为什么我认为这种行为真的不那么重要。对于事务处于打开状态的情况,应用程序必须在提交、回滚或询问之间进行选择。选择提交对我来说似乎是一个合乎逻辑的选择,尽管其他两个也可以。大多数情况下,您不会发出 DML 来回滚,这就是为什么我认为提交是个好主意。但正如已经说过的:不要让你的脚本首先依赖于它。
【解决方案4】:

好问题。

我查看了 metalink 并针对 1998 年在正常退出时提交的默认行为提出了一个错误(或更改请求)。如果您可以访问 metalink,请查找错误 633247。

【讨论】:

  • 其实上周 :) 在新的 11gr2 版本中
【解决方案5】:

有趣的是,随着本周 (2009-09-03) 的 11gR2 发布,SQL*Plus 现在可以选择在退出时提交或回滚。文档here

我猜在接下来的几周/几个月内,将会有一个 11gR2 Instant Client,您可以将其用于您当前的数据库并获得您想要的行为

注意事项。如果你 DISCONNECT or CONNECT 到另一个会话,它仍然会隐式提交事务(根据文档)。

【讨论】:

  • 如果你愿意,我想看看那个链接:)
  • 链接已终止
【解决方案6】:

与使用 Oracle 驱动程序的 jdbc 连接在关闭连接时隐式提交 txn 的方式一致。

【讨论】:

  • 我似乎找不到记录在哪里。不是我怀疑你,而是你能引用你的来源吗?
  • ojdbc14.jar 当调用 OracleManagedConnection cleanup 时,它会检查当前是否正在进行有效事务。在事务正在进行的情况下会抛出 IllegalStateException。
【解决方案7】:

在退出时提交对我来说似乎是合乎逻辑的事情,通常ROLLBACK 是例外,当出现问题时我们会回滚,当您插入、更新或删除数据时,您的意思是这样做,即COMMIT

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 2011-11-04
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    相关资源
    最近更新 更多