版权声明:资源类仅用于学习交流,禁止商用!!! https://blog.csdn.net/GentleCP/article/details/88580680
前言
做项目的过程经常用到数据库,有时候我们需要实时更新数据库的数据到程序中,例如再连接数据库后,数据库某个表中新增了一条数据,将这条数据捕捉到,但有时候会出现查询的数据和上次查询的一样,没有更新数据,这种情况发生在事务型数据库,例如MySQL,即需要commit提交事务的。
【测试环境】
language: python3.6.7
os: windows10
DB: MySQL8.0.13
附:如果不懂python如何连接数据库的可以参考我另一篇文章主流数据库的使用教程
一、无法更新数据原因
因为MySQL事务隔离,InnoDB默认的隔离级别是可重复读(REPEATABLE READ),在同一个事务中读取的值总是一样的。
为了感知到变化,必须重新获取一个事务,理论可解决的方法如下:
1、关闭conneciton重新获取
2、调用commit,将该事务提交
3、改变mysql的事务隔离级别到READ COMMITED
本文演示前两种办法,第三种办法不推荐使用,因为事务本身就是保护操作的,不建议修改事务隔离级别。
二、演示
首先,创建一个数据库和对应的表,用于测试,如下:
目前有10条数据
基础代码:
import pymysql
import time
database = {
'host': 'localhost',
'port': 3306,
'user': 'root',
'passwd': 'root',
'db': 'log',
'charset': 'utf8',
}
def conn_db(DB):
'''
:param DB: DB config
:return: connect object or Exception
'''
try:
connect = pymysql.Connect(
host=DB['host'],
port=DB['port'],
user=DB['user'],
passwd=DB['passwd'],
db=DB['db'],
charset=DB['charset']
)
return connect, True
except Exception as e:
return e, False
def get_data(connect,sql, table_name):
cursor = connect.cursor()
try:
cursor.execute(sql)
datas = cursor.fetchall() # 暂时获取全部数据
print('查询%s成功!共获取到%s条数据' % (table_name, len(datas)))
for data in datas:
print(data)
except Exception as e:
print('查询%s失败!错误原因:%s' % (table_name, e))
conn, is_conned = conn_db(database)
table = 'test_table'
sql = "select * from %s" % table
while True:
# 不断获取新数据
get_data(conn,sql,table)
time.sleep(30)
代码实现了每30秒从数据库的test_table中获取数据打印。但是我在数据库后台添加了数据之后发现仍然打印的是之前的内容。
结果如下:
方法一、关闭connection重新获取
这个方法很直白,相当于与数据库重新连接一次。在每次get_data前重新建立一次连接,如下:
效果:
方法二、commit提交事务
相当于将现在处理的事务提交了,这样就不会在现有事务中获取之前的数据,如下:
效果:
小结
相比于方法一、建议使用方法二,因为重新建立连接不如提交事务快速,而且每次重复进行连接也没有意义。