python3连接mysql使用事务功能异常

[toc]

Mysql中InnoDB事务

背景

python3连接mysql使用事务功能异常:

当第一条SQL成功执行,第二条SQL失败的情况下,理应两条SQL回滚,而下面代码执行时,第一条SQL成功执行并没有回滚

# -*- coding: utf-8 -*-
# @Time    : 2019/11/26 14:22
# @Author  : lgz
# @File    : test_mysql.py
# @Software: PyCharm


def CreateDBPool(dbconfig):
    import pymysql
    from pymysql.cursors import DictCursor
    from DBUtils import PooledDB, PersistentDB
    import telnetlib
    telnetlib.Telnet(dbconfig['host'], int(dbconfig['port']), timeout=5)
    dbpool = PersistentDB.PersistentDB(
        creator = pymysql,  # 使用链接数据库的模块
        maxusage = None,  # 一个链接最多被使用的次数,None表示无限制
        setsession = [],  # 开始会话前执行的命令
        ping = 0,  # ping MySQL服务端,检查服务是否可用
        closeable = False,  # conn.close()实际上被忽略,供下次使用,直到线程关闭,自动关闭链接
        threadlocal = None,  # 本线程独享值的对象,用于保存链接对象
        autocommit = False,
        user=dbconfig['user'],
        passwd= dbconfig['passwd'],
        host =dbconfig['host'],
        port=dbconfig['port'],
        db=dbconfig['db']
    )
    return dbpool

dbconfig = {
    'host': xxxxx,
    'port': 3306,
    'user': xxx,
    'passwd': xxxx,
    'db': xxxx,
    'charset': 'utf8'
}
dbpool = CreateDBPool(dbconfig)
db=dbpool.connection()
cur=db.cursor()
try:
    cur.execute("""INSERT INTO `job_summary` (`job_id`, `job_name`, `user`, `create_time`, `modify_time`, `status`) 
VALUES ('job_id_ccc_1574751415', '测试任务名', '6666', '1574751416', NULL, NULL);
""")

    cur.execute("""INSERT INTO `job_summary` (`job_id2`, `job_name`, `user`, `create_time`, `modify_time`, `status`) 
VALUES ('123', '测试任务名', '6666', '1574751416', NULL, NULL);
""")
    # cur.execute("""INSERT INTO `root_timermanage_service`.`timer_detail_jobinfo` (`id`, `uuid`, `timer_func_name`, `func_args`, `request_url`, `request_data`, `request_result`, `created_at`, `updated_at`, `timer_id`) VALUES ('1', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);""")
except Exception as e:
    print(e)
    db.rollback()
else:
    db.commit()
finally:
    cur.close() # or del cur
    db.close() # or del db

原因

查看Mysql的存储引擎发现是MyISAM(InnoDB 支持事务,MyISAM 不支持事务)

MyISAM 和 InnoDB 的区别

  • InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

  • InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;

  • InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

  • InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

  • InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

参考链接

https://www.zhihu.com/question/20596402

本文作者:朝圣

本文链接:www.zh-noone.cn/2019/12/python3连接mysql使用事务功能异常

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!

python3使用requests编码异常
0 条评论