【问题标题】:single "commit" statement without "begin transaction"没有“开始交易”的单个“提交”语句
【发布时间】:2012-02-06 15:41:33
【问题描述】:

我正在使用带有 mysqldb 适配器的 web2py dal 连接到 mysql 服务器。

我的问题:

  1. 为什么在“set autocommit=0”之后需要一个“commit”而不引导“begin transaction
  2. 如果 autocommit=0,“select”语句是否开始事务?

服务器信息: innodb 引擎 自动提交=1(默认值) tx_isolation=repeatable-read(默认值)

general_log:

100356 10:00:00 123456 Connect  dummy@172.0.0.1 on dummydb
123456 Query    SET NAMES 'utf8'
123456 Query    SET AUTOCOMMIT = 0
123456 Query    COMMIT
123456 Query    SET FOREIGN_KEY_CHECKS=1
123456 Query    SET sql_mode='NO_BACKSLASH_ESCAPES'

【问题讨论】:

    标签: mysql transactions commit autocommit


    【解决方案1】:

    呃……因为你禁用了自动提交????

    这里有一个很好的解释:

    http://rpbouman.blogspot.com/2007/02/mysql-transactions-and-autocommit.html

    启用自动提交后,每个语句都包含在自己的语句中 交易。语句的成功执行是隐式的 紧随其后的是 COMMIT,并且发生错误时中止 事务,回滚任何更改。

    默认情况下,MySQL 中启用了自动提交。

    换句话说:

    1. “事务”不一定只是“将多个语句作为一个原子实体执行”

    2. 自动提交给您一个语句 == 1 个事务的“错觉”

    3. 事实上,“automcommit off”为您提供“一个语句 == 0 个事务”

    来自同一链接:

    ... 关闭自动提交的全部意义在于您可以发出 多个语句并同时提交它们。

    【讨论】:

    • 感谢乔纳森。所以“开始”是在这种情况下隐式发出的。另一个问题:会话 A 中的“提交”语句会将会话 B 中的已提交更改带到会话 A 中吗? (tx_isolation=repeatable-read)
    • 这是 Paul 的回答...但是,是的,在您提交之后,您将启动一个新事务,因此您还可以看到自您开始之前的事务以来其他人对数据库的提交更改。
    【解决方案2】:

    在标准 SQL 中,您(几乎)总是在事务中。如果您执行 COMMIT 或 ROLLBACK,则下一条语句将启动一个新事务。因此,如果您希望更改生效,您必须提交它们。

    如果您开启了 AutoCommit,那么每条语句都是一个单例事务,如果成功则自动提交,如果失败则回滚。

    当您关闭 AutoCommit 时,您必须提交以确保数据库更改生效。

    一些 DBMS 在这个主题上有细微的变化。

    特别是 Informix 有一种数据库模式,其中 AutoCommit 在您执行显式 BEGIN [WORK] 之前一直处于开启状态;那么你在一个事务中,直到你执行 COMMIT [WORK] 或 ROLLBACK [WORK]。它还有一个“MODE ANSI”,其行为与标准 SQL 中的一样;它有一个未记录的模式,根本没有交易。

    话虽如此,您所展示的陈述并不是不言而喻的,确实需要交易支持。它往往是 DML 语句(SELECT、INSERT、DELETE、UPDATE、MERGE 等),有时是需要事务支持的 DDL 语句。一些 DBMS 不允许回滚 DDL 语句(Oracle);其他人做 (Informix)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多