关于mysql:万答2一样的Python代码为什么可以删表却不能更新数据

43次阅读

共计 2369 个字符,预计需要花费 6 分钟才能阅读完成。

欢送来到 GreatSQL 社区分享的 MySQL 技术文章,如有疑难或想学习的内容,能够在下方评论区留言,看到后会进行解答

问题

运行上面的这段 Python 代码,却总是无奈更新数据:

import pymysql
conn=pymysql.connect(
host = '127.0.0.1', user = 'yewen', passwd='YeWen.3306',
port= 3306, db='test', charset='utf8mb4')
cur = conn.cursor()
sql = "update t1 set c3 = rand()*10240 where c1 = rand()*1024"
cur.execute(sql)
cur.close()
conn.close()
而运行上面的这段看起来一样的代码,却能够失常删表:import pymysql
conn=pymysql.connect(
host = '127.0.0.1', user = 'yewen', passwd='YeWen.3306',
port= 3306, db='test', charset='utf8mb4')
cur = conn.cursor()
sql = "drop table tmp1"
cur.execute(sql)
cur.close()
conn.close()

答复

其实问题并不简单,有几个起因:

  • 1. 要写入的表是 InnoDB 引擎,而 InnoDB 引擎是反对事务的,也就是写入后,要提交事务才是真正实现写入。
  • 2. 连贯数据库时,须要自行设定事务主动提交模式,是开启还是敞开。
  • 3.pymysql 模块里,默认不启用主动提交模式。
    所以对表进行 DML 操作时,须要提交事务后能力胜利。
  • 4. 而删除表是 DDL 操作,目前 DDL 操作还不反对事务,所以即使没有开启主动提交,也能胜利。

晓得下面的起因就好办了。咱们先看下 pymysql 源码中对于主动提交的设定:

[root@yejr-mgr1 pymysql]# cat /usr/lib/python2.7/site-packages/pymysql/connections.py
...
#约 158 行左近
 158     :param autocommit: Autocommit mode. None means use server default. (default: False)
...

所以,解决办法有好几种:

  1. 在连贯初始化时开启主动提交模式,例如:
# 设置属性 autocommit= 1 亦可
conn=pymysql.connect(
host = '127.0.0.1', user = 'yewen', passwd='YeWen.3306',
port= 3306, db='test', charset='utf8mb4', autocommit=True)
  1. 或者执行完 DML 操作后,再执行一次 commit 申请,例如:
sql = "update t1 ...
cur.execute(sql)
cur.execute("commit")
  1. 又或者在创立完连贯后,批改 autocommit 模式,例如:
conn=pymysql.connect(
host = '127.0.0.1', user = 'yewen', passwd='YeWen.3306',
port= 3306, db='test', charset='utf8mb4')
cur = conn.cursor()
cur.execute("set autocommit=1")

到这里,主动提交的问题解决了。

但还要更进一步,开启或敞开 autocommit 有什么利弊呢?简言之,有几点倡议:

  • 1. 当有大批量数据更新时,能够先敞开 autocommit,等事务完结后,再手动提交。事务 commit 时要刷新 redo log、binlog 等,代价还是比拟大的。
  • 2. 敞开 autocommit 的毛病在于,当遗记被动提交事务时,可能会造成相应的行锁始终持有不开释,其余事务会被长时间阻塞,如果是线上生产环境,则可能造成严重后果(业务长时间不可用)。
  • 3. 因而,须要依据理论状况动静调整 autocommit 的模式,并没有通用的设置。
  • 4. 不少开发框架都会默认设置 set autocommit=0,更有甚者,每次执行一个 SQL 前,都要发送一次 set 申请,减少了无谓的开销,如果有这种状况,能够自行调整开发框架的代码。

Enjoy MySQL :)

文章举荐:

技术分享 | MGR 最佳实际 (MGR Best Practice)
https://mp.weixin.qq.com/s/66…

技术分享 | 万里数据库 MGR Bug 修复之路
https://mp.weixin.qq.com/s/Ia…

Macos 零碎编译 percona 及局部函数在 Macos 零碎上运算差别
https://mp.weixin.qq.com/s/jA…

技术分享 | 利用 systemd 治理 MySQL 单机多实例
https://mp.weixin.qq.com/s/iJ…

产品 | GreatSQL,打造更好的 MGR 生态
https://mp.weixin.qq.com/s/By…

产品 | GreatSQL MGR 优化参考
https://mp.weixin.qq.com/s/5m…

对于 GreatSQL

GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。

Gitee:
https://gitee.com/GreatSQL/Gr…

GitHub:
https://github.com/GreatSQL/G…

微信 &QQ 群:

可扫码增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群,亦可间接扫码退出 GreatSQL/MGR 交换 QQ 群。

本文由博客一文多发平台 OpenWrite 公布!

正文完
 0