2012-01-10 130 views
2

我正在使用web2py dal与mysqldb适配器连接到mysql服务器。没有“开始事务”的单个“提交”语句

我的问题:

  1. 为什么它需要一个单一的 “提交” 没有领先后 “开始交易” “一套自动提交= 0
  2. 没有 “选择” 的声明开始一个事务,如果autocommit = 0?

服务器信息: InnoDB引擎 自动提交= 1(默认值) TX_ISOLATION =重复读取(默认值)

general_log:

100356 10:00:00 123456 Connect [email protected] 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' 

回答

7

呃......因为你禁用自动提交????

这里有一个很好的解释:

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

自动提交启用,每个语句都是在其自己的 事务中包裹着。语句的成功执行是隐含地 ,后跟一个COMMIT,并且发生错误会中止事务,回滚所有更改。

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

换句话说:

  1. “交易”不一定只有“执行多个语句作为一个原子实体”

  2. 自动提交给你一个说法“错觉” == 1交易

  3. 其实“automcommit off”给你“一个语句== 0个交易”

从相同的链接:

... 已经关闭自动提交的全部要点是,你可以发出 多条语句并提交他们的一次。

+0

谢谢jonathan。所以在这种情况下隐含地发布“开始”。另一个问题:会话A中的“提交”声明是否将会话B中的已提交更改引入会话A? (tx_isolation =可重复读取) – 2012-01-10 08:10:30

+0

这是Paul的答案......但是,在COMMIT之后,你开始一个新的事务,所以你也可以看到自从你开始前面的事务以来,其他人对数据库的改变。 – 2012-01-10 15:14:14

3

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

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

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

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

特别是,Informix具有一个数据库模式,其中AutoCommit处于打开状态,直到您执行明确的BEGIN [WORK];那么在进行COMMIT [WORK]或ROLLBACK [WORK]之前,您将处于事务中。它也有一个'MODE ANSI',其行为与标准SQL相同;它有一个没有记录的模式,根本没有交易。

综上所述,您所展示的陈述并非不言自明,真正需要交易支持。它往往是DML语句(SELECT,INSERT,DELETE,UPDATE,MERGE等),有时还需要事务支持的DDL语句。某些DBMS不允许回滚DDL语句(Oracle);其他人(Informix)。