pymysql遇到的坑,更新数据后,重新读取字段数据不更新。
写个小脚本,准备全部用MySQL做数据库,redis一直没好好学,所以不想用。
逻辑是这样的,我这边查寻一个数据,如果这个数据存在就赋值属性,如果不存在,执行任务写入数据库。
然后再次执行查寻数据,写入对象属性。
# 初始化用户的uid,uid可以从用户收入数据库表中读取 def _initialize_uid(self): # 读写的时候需要重新连一下数据库,保证读取的数据的跟新。 uid_info = self.db.selectDb(SEARCH_USER_UID, (self.account,)) # 假如不能读出来,执行用户的收入表跟新数据。 if uid_info: self.uid = uid_info[0][0] else: print(123)
# 写入数据库信息, if get_money_income(self.account)[0]: time.sleep(2)
# 重新执行该方法去读取数据 self._initialize_uid()
假如你的数据库一致保持着链接,发现我采取这种递归的模式更本无法读取到写入后数据的数据库信息。暂时没有什么好的办法。
唯一的解决办法是每次查寻的时候,可以新建一个连接对象,但这样的话,感觉对数据库压力会比较大。
后续我也使用过多线程进行数据库操作,类似生产者与消费者的关系,记得一个写,一个读可以读取到数据库跟新,难道单线程自己写好,自己读取写好的数据无法完成?
这样的话,感觉使用就会带来非常大的麻烦。
已经找到解决方法
今天做一个监控后台数据库数据的程序中,使用了pymysql,但是在每次使用游标对象select对象时数据都是一个样。
原因在于:1. Mysql的存储引擎InooDB的事务隔离级别默认是 可重复读(Repeatable Read),例如A客户端事务未提交,而B客户端事务修改了数据,A客户端只能读取到小于等于当前事务版本号的数据(快照读),所以只有提交完事务后,开启新的事务中才能读取到新的数据。
2. PyMysql模块的连接对象默认是没有自动提交事务的,需要我们用一个commite()方法才能提交,不像我们在MySQL客户端中,每次select,update,delete都帮我们自动提交事务,所以只要我们手动提交了事务,再重新select就可以查到新的数据。
解决方法:
方法一: 每次在用游标对象执行完查询语句后都手动提交
from pymysql import *
con = connect(host = ‘xxxx’, port = xxxx, database = ‘xxxx’, user = 'root', password = '123123', charset = 'utf8')
cs = con.cursor()
sql = ‘select * from xxx where id = 1’
# 开启事务
cs.execute(sql)
# 手动关闭事务
con.commit()
print(cs.fetchone()) #数据a
# 再开启事务
cs.execute(sql)
# 再关闭事务
con.commit()
print(cs.fetchone()) #更新后的数据
方法二.创建一个自动帮我们提交事务的连接对象
con = connect(host = 'localhost', port = 3306, database = 'smarthome', user = 'root', password = '123123', charset = 'utf8’, autocommit = 1)
这样就不用每次查数据都手动结束事务
但是修改数据要小心,因为自动提交,没有commit也会生效。
————————————————
版权声明:本文为CSDN博主「JackChan7」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/JackChan7/java/article/details/88741060
主要还是对事务的特性的理解还是停留在概念上,这次问题的出现让我对事务有了更深的认识。