python+mysql分布式事务


import pymysql
import datetime,time
import os,sys

os.environ['NLS_LANG']='SIMPLIFIED CHINESE_CHINA.UTF8'
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
SQL脚本 = os.path.join(BASE_DIR,"\PycharmProjects\main\LC_TJYB\日常运维脚本\数据传输\SQL脚本\\")
class myYbsxhf():
    def __init__(self, sqxh):
        self.sqxh = sqxh
    def read_sql_execute(self, sql_file, is_cx, s1):
        con = pymysql.connect(host='', port=3306, user='sqzx', passwd='', db='sqzx', charset='utf8')
        cursor = con.cursor()
        sql = open(sql_file, 'r', encoding='utf8')
        sqltxt = sql.readlines()
        sql.close()
        sql = "".join(sqltxt)
        sql = sql.replace('&sqxh', self.sqxh)
        sql = sql.replace('&s1', s1)
        sql = sql.replace('None', 'null')
        print(sql)
        rs = ''
        try:
            cursor.execute(sql)
            if is_cx==0:
                con.commit()
            else:
                rs = cursor.fetchall()
        except Exception as e:
            print(e)
        finally:
            cursor.close()
            con.close()
        return rs
    def main(self):
        # self.read_sql_execute(SQL脚本+'ins_ybsxxxbfk.sql', 0, '')
        # res = self.read_sql_execute(SQL脚本 + 'sel_ybsxxxbfk.sql', 1, '')
        # swjg_dm = res[0][0]
        swjg_dm = '14419120000'
        if swjg_dm == swjg_dm[:7]+'0000':
            if swjg_dm == swjg_dm[:5] + '000000':
                str1 = "jc1='"+swjg_dm+"'"
            else:
                str1 = "jc1='"+swjg_dm[:5]+"000000',jc2='"+swjg_dm+"'"
        else:
            str1 = "jc1='"+swjg_dm[:5]+"000000',jc2='"+swjg_dm[:7]+"0000',jc3='"+swjg_dm+"'"
        self.read_sql_execute(SQL脚本 + 'up_ybsxxxbfk.sql', 0, str1)

以上是python操作mysql数据库代码,对mysql分库的分表进行插入、更新、删除处理,程序运行报错:
[TDDL-4603][ERR_ACCROSS_DB_TRANSACTION] Transaction accross db is not supported in current
帮忙看下这个python程序是否能改成自动比对事务进行提交,像navicat一样,执行语句都能正常执行

根据报错信息可以看出,当前的操作涉及到了跨数据库的事务,而当前的数据库连接并没有开启分布式事务的支持,因此无法执行跨数据库的事务操作,所以需要将数据库连接修改为支持分布式事务的连接。以下是修改后的代码示例:

import pymysql
import datetime,time
import os,sys

os.environ['NLS_LANG']='SIMPLIFIED CHINESE_CHINA.UTF8'
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
SQL脚本 = os.path.join(BASE_DIR,"\PycharmProjects\main\LC_TJYB\日常运维脚本\数据传输\SQL脚本\\")

class myYbsxhf():
    def __init__(self, sqxh):
        self.sqxh = sqxh
        self.con = pymysql.connect(host='', port=3306, user='sqzx', passwd='', db='sqzx', charset='utf8',
                                   autocommit=False, transaction_level="READ COMMITTED")

    def read_sql_execute(self, sql_file, is_cx, s1):
        cursor = self.con.cursor()
        sql = open(sql_file, 'r', encoding='utf8')
        sqltxt = sql.readlines()
        sql.close()
        sql = "".join(sqltxt)
        sql = sql.replace('&sqxh', self.sqxh)
        sql = sql.replace('&s1', s1)
        sql = sql.replace('None', 'null')
        print(sql)
        rs = ''
        try:
            cursor.execute(sql)
            if is_cx==0:
                self.con.commit()
            else:
                rs = cursor.fetchall()
        except Exception as e:
            self.con.rollback()
            print(e)
        finally:
            cursor.close()
        return rs

    def main(self):
        swjg_dm = '14419120000'
        if swjg_dm == swjg_dm[:7]+'0000':
            if swjg_dm == swjg_dm[:5] + '000000':
                str1 = "jc1='"+swjg_dm+"'"
            else:
                str1 = "jc1='"+swjg_dm[:5]+"000000',jc2='"+swjg_dm+"'"
        else:
            str1 = "jc1='"+swjg_dm[:5]+"000000',jc2='"+swjg_dm[:7]+"0000',jc3='"+swjg_dm+"'"
        self.read_sql_execute(SQL脚本 + 'up_ybsxxxbfk.sql', 0, str1)

    def __del__(self):
        self.con.close()

主要修改如下:

  1. 将 pymysql.connect() 函数的 autocommit 参数设置为 False,表示关闭自动提交事务的功能,需要手动进行事务提交或回滚。
  2. 将 pymysql.connect() 函数的 transaction_level 参数设置为 "READ COMMITTED",表示设置事务的隔离级别为读已提交,保证数据的一致性。
  3. 在需要提交事务的地方,调用 self.con.commit() 进行手动提交事务,如果出现异常则调用 self.con.rollback() 进行事务回滚。