我有两个程序:一个填充和更新数据库,另一个每隔10秒从数据库中选择信息。
我使用pymysql。
当我更新数据库并提交数据时,我可以用命令行在数据库中看到结果,但是另一个程序有相同的输出并且没有得到新的数据!
我需要做一个特殊的查询吗 SELECT
? 在所有查询之前,是否需要关闭连接并重新打开它?
我创造了 GetData
课程开始时 get_data
每10秒调用一次。
class GetData:
def __init__(self):
self.conn = pymysql.connect(host='localhost', user='root', password='', db='mydb', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
def get_data(self, data):
with self.conn.cursor() as cursor:
self.sql = "SELECT id_data, somedata FROM mytable WHERE (%s = 'example');"
cursor.execute(self.sql, (data,))
return cursor.fetchall()
def close_conn(self):
self.conn.close()
填充数据库的程序:
class FillDb:
def __init__(self):
self.conn = pymysql.connect(host='localhost', user='root', password='', db='mydb', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
#added this line but doesen't help!
self.conn.autocommit(True)
def add_in_db(self, data):
with self.conn.cursor() as cursor:
self.sql = "INSERT INTO mytable (somedata) VALUES (%s);"
cursor.execute(self.sql, (data,))
self.conn.commit()
1条答案
按热度按时间368yc8dk1#
为什么看不到更新:
该行为的原因是innodb的默认隔离级别repeatable read。对于repeatable read,第一个非锁定select将建立一个表示该时间点数据的快照。所有连续的非锁定选择从同一快照读取。其他事务对数据库的更新不会反映在快照中,因此保持透明。
提交事务(或关闭事务并创建一个新的事务)将导致在下一个查询中创建一个新的快照,表示数据库中该时间点的数据。这就是mysql如何实现一致的非锁定读取,作为acid遵从性策略的一部分。
为什么?
with self.conn
工作原理:在pymysql中,有两个(相关的)contextmanager实现,一个在游标上(或多或少是“文档化的”),另一个在连接上(可以在代码中找到:d)。
当你使用
with self.conn.cursor() as cursor:
是游标的实现生效了。输入返回的上下文self
(从cursor()
上的方法self.conn
); 离开上下文最终关闭了光标。它对交易没有影响。使用时
with self.conn as cursor
有效的是连接的实现。输入上下文将返回调用self.cursor()
; 离开上下文commit
或者rollback
在交易中。光标也是隐式关闭的。所以,对
self.commit
当离开连接实现的上下文时,事务中的现有快照将“过期”,并强制在循环的下一次迭代中创建一个新的快照,该循环可能包含插入项,只要它们的提交在创建所述新快照之前完成。