在 PyMySQL 中回滚多个查询

Posted

技术标签:

【中文标题】在 PyMySQL 中回滚多个查询【英文标题】:Rollback multiple queries in PyMySQL 【发布时间】:2021-09-22 21:56:17 【问题描述】:

已发布了与此类似的问题,但不幸的是,没有一个建议的解决方案对我有用。

我想看看我是否可以在一个 try 子句中编写两个查询,并在其中一个抛出异常时让它们都回滚。为了确保抛出异常,我只是尝试创建同一个表两次。

def function():
        try:
            cursor = connection.cursor()
                
            q1 = "CREATE TABLE 0_test_table (column1 varchar(255))"
            cursor.execute(q1)
            
            q1 = "CREATE TABLE 0_test_table (column1 varchar(255))"
            cursor.execute(q1)
                
        except pymysql.Error as e:
            print("Exception encountered")
            print(e)
            try:
                connection.rollback()
            except:
                print("rollback failed")
                pass
            
        else:
            connection.commit()
            connection.close()
                   
function()

打印出来的:

Exception encountered
(1050, "Table '0_test_table' already exists")

由于异常是由查询引发的,而不是由回滚引发的,我认为它一定是回滚了更改。我检查了数据库并创建了表。为什么回滚不起作用?这也引出了关于 commit 方法的作用的问题。由于我从未在代码中使用 else,因此我从未使用过 commit 方法,但事情已明确提交。

我试图改编我在 O'Reilly 网站here 上找到的一个示例。这导致我有:

def function():
    try:
        connection.begin()
        cursor = connection.cursor()
            
        q1 = "CREATE TABLE 0_test_table (column1 varchar(255))"
        cursor.execute(q1)
        
        q1 = "CREATE TABLE 0_test_table (column1 varchar(255))"
        cursor.execute(q1)
        
        cursor.close()
        connection.commit()
            
    except pymysql.Error as e:
        print("Exception encountered")
        print(e)
        try:
            connection.rollback()
        except:
            print("rollback failed")
            pass
               
function()

再次打印:

Exception encountered
(1050, "Table '0_test_table' already exists")

再次在数据库中创建了表。

【问题讨论】:

您的连接对象上是否启用了autocommit? 我认为默认情况下它是关闭的,但无论哪种方式我都确保它不是通过将 autocommit=False 放入 connect() 【参考方案1】:

正如您在引用中看到的那样,ROLLBACK 中的 CREATE TABLE 无法完成。

“InnoDB 中的 CREATE TABLE 语句作为单个事务处理。这意味着来自用户的 ROLLBACK 不会撤消用户在该事务期间所做的 CREATE TABLE 语句。”

见manual

【讨论】:

哦,哎呀,这是 MySQL 的东西,而不是 PyMySQL 的东西。谢谢nbk!

以上是关于在 PyMySQL 中回滚多个查询的主要内容,如果未能解决你的问题,请参考以下文章

如何在SQL Server 2005中回滚UPDATE查询?

如何在 SQL Server 2005 中回滚 UPDATE 查询?

在 Mercurial 中回滚多个提交(在推送到公共之前)

如何在 SQL Server 中回滚或提交事务

mysql之子查询视图事务及pymysql等(待修改)

pymysql操作数据库