python - DB - 未commit的坑,及三种出坑方法
坑:
查询数据库 -> 修改数据库内容 -> 再次查询数据库,会发现两次查询结果一样,修改的内容未被查询出来
import MySQLdb conn = MySQLdb.connect( host='192.168.1.101', port=3306, user='123', passwd='123', db='test', charset='utf8' ) cur1 = conn.cursor() sql1 = "select id from user" cur1.execute(sql1) nn = cur1.fetchall() # 111 print(nn) cur1.close() # ---修改数据库中id的值为222--- cur2 = conn.cursor() sql2 = "select id from user" cur2.execute(sql2) mm = cur2.fetchall() # 111 print(mm) cur2.close() conn.close()
这是因为python的Mysqldb默认关闭autocommit,任意执行一个select子句,对于Mysql5.5以上版本,都会造成MATADATA LOCK阻塞
第一次查询后,产生阻塞,所以后续不能查询到最新数据
解决方法:
python的MySQLdb的API把数据库更新语句做为事务来执行,这样的话,虽然使用execute语句执行了sql,但是并没有真的对数据库进行改变,除非使用commit方法来显式的提交事务才可以对数据库造成影响,否则,数据库会自动回滚。所以解决方案:增加commit,有三种方式可选:
- autocommit=True # 方法一:连接数据库的时候,就开启自动提交
- conn.autocommit(True) # 方法二:执行sql语句之前,设置自动提交
- conn.commit() # 方法三:执行sql语句之后提交
import MySQLdb conn = MySQLdb.connect( host='192.168.0.1', port=3306, user='abc', passwd='111111', db='bbbbb', charset='utf8', autocommit=True # 方法一:连接数据库的时候,就开启自动提交 ) # conn.autocommit(True) # 方法二:执行sql语句之前,设置自动提交 cur = conn.cursor() sql3 = "insert into tb_3 values ('王五', '化学', 99, 3), ('王五', '物理', 98, 3)" cur.execute(sql3) # conn.commit() # 方法三:执行sql语句之后提交 cur.close() conn.close()
ps:
此坑只存在于mysql引擎是InnoDB的情况下
如果你的mysql引擎是Myisam,则只要调用execute就会提交事务