【问题标题】:Does a transaction start even on SELECT?事务是否在 SELECT 上开始?
【发布时间】:2012-02-08 13:21:21
【问题描述】:

我在docs读到:

...因为事务在游标执行查询时开始,但在执行 COMMIT 或 ROLLBACK 时结束 连接对象。

import MySQLdb

db = MySQLdb.connect(user="root", db="test")
c = db.cursor()
c.execute("SELECT * FROM books")
print c.fetchall()

我怀疑 MySQLdb 即使在不修改数据的查询(如 SELECT)上也会启动事务,因为很难知道查询是否只读取数据而不写入数据。

  1. 是真的吗?
  2. 如果是这样,这意味着我应该在每次查询后执行cursor.commit(),以确保没有表被锁定?
  3. 其他我不知道的问题?

谢谢

【问题讨论】:

    标签: python mysql mysql-python


    【解决方案1】:

    是的,SELECT 语句与其他语句类似,因此事务开始。

    如果你想避免这种情况,你可以这样做:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
    SELECT * FROM books ;
    COMMIT ;
    

    详细说明:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
    

    表示以下指令可以读取已修改但尚未收到COMMIT 的行。 这种事务不会获得排他锁。

    第二部分SELECT * FROM books ; 显然是SQL statement,第三部分COMMIT ; 结束事务并使其“永久”。 在这种情况下,不会进行任何写入,因此COMMIT 仅用于结束事务和

    【讨论】:

    • 您能否解释一下您的示例,以及为什么仍然需要commit
    • @warwaruk:这个问题更新了吗?因为我记得那是不同的。
    • 好吧,我记不太清了。但是,他在第 2 点询问是否必须在每次更新后执行cursor.commit,我告诉他,如果他使用 sql 查询的 sn-p,他甚至可以忘记“每次查询都提交游标”。有关更多详细信息,请参阅我将要进行的更新。
    【解决方案2】:
    1. 确实如此,但它也会在每次查询后自动提交,因为mysql客户端默认以autocommit=1开头

    2. 你不应该这样做,因为SELECT 在语句执行后不会持有任何锁。在实践中,显式提交甚至可能导致显着减速。

    3. 可能有用:Why connection in Python's DB-API does not have "begin" operation?

    【讨论】:

    • autocommit=1 不适用于 Python MySQLdb!您必须明确设置它。这是 Python 中误解的常见来源,例如“我刚刚插入的数据在哪里?”。
    • @ocaso-protal,嗯,真的。为什么我很久以前从我的连接设置中删除了 init_command 参数设置 autocommit=0 ?
    猜你喜欢
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2013-04-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多