我使用MySQLdb模块从python使用MySQL 5.0。
考虑一个简单的函数来加载和返回整个数据库表的内容:
def load_items(connection):
cursor = connection.cursor()
cursor.execute("SELECT * FROM MyTable")
return cursor.fetchall()
此查询旨在成为一个简单的数据加载,并且除了单个SELECT
语句之外没有任何事务行为。
运行此查询后,可能需要一段时间再次使用相同的连接来执行其他任务,尽管其他连接仍然可以在数据库上同时运行。
我应该在connection.commit()
通话后尽快致电cursor.execute(...)
,以确保该操作未在连接上留下未完成的交易吗?
答案 0 :(得分:11)
您需要考虑以下两点:
MySQL中的默认隔离级别为REPEATABLE READ
,这意味着如果在事务内部运行SELECT
两次,即使其他事务已提交更改,您也会看到完全相同的数据。
大多数时候,人们希望在运行第二个select语句时看到提交的更改 - 这是READ COMMITTED
隔离级别的行为。
如果您没有更改MySQL中的默认级别,并且执行期望在同一事务中运行SELECT两次时看到数据库中的更改 - 那么您无法在“相同”的交易,您需要提交第一个SELECT
声明。
如果您实际上想要在事务中查看数据的一致状态,那么您应该不提交。
然后几分钟后,第一个进程执行一个事务性操作并尝试提交。这个提交会失败吗?
这完全取决于您对“是交易”的定义。你在关系数据库中做的任何事情都是“事务性的”(实际上对于MySQL来说并不完全正确,但是为了论证,如果你只使用InnoDB作为你的存储引擎,你可以假设这一点)。
如果“第一个进程”仅选择数据(即“只读事务”),那么当然提交将起作用。如果它试图修改另一个事务已经提交的数据并且 正在运行REPEATABLE READ
,则可能会出现错误(等待任何锁定释放后)。在这种情况下,我不是100%关于MySQL的行为。
您应该使用您喜欢的SQL客户端通过两个不同的会话手动尝试此操作来了解该行为。也要改变你的隔离级别,以便看到不同级别的效果。