本帖最后由 GreatSQL万答 于 2022-8-17 17:27 编辑
其实问题并不复杂,有几个原因:- 要写入的表是InnoDB引擎,而InnoDB引擎是支持事务的,也就是写入后,要提交事务才是真正完成写入。
- 连接数据库时,需要自行设定事务自动提交模式,是开启还是关闭。
- pymysql模块里,默认不启用自动提交模式。
- 所以对表进行DML操作时,需要提交事务后才能成功。
- 而删除表是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)
复制代码2. 或者执行完DML操作后,再执行一次commit请求,例如: - sql = "update t1 ...
- cur.execute(sql)
- cur.execute("commit")
复制代码3. 又或者在创建完连接后,修改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有什么利弊呢?简言之,有几点建议: - 当有大批量数据更新时,可以先关闭autocommit,等事务结束后,再手动提交。事务commit时要刷新redo log、binlog等,代价还是比较大的。
- 关闭autocommit的缺点在于,当忘记主动提交事务时,可能会造成相应的行锁一直持有不释放,其他事务会被长时间阻塞,如果是线上生产环境,则可能造成严重后果(业务长时间不可用)。
- 因此,需要根据实际情况动态调整autocommit的模式,并没有通用的设置。
- 不少开发框架都会默认设置 set autocommit=0,更有甚者,每次执行一个SQL前,都要发送一次set请求,增加了无谓的开销,如果有这种情况,可以自行调整开发框架的代码。
|