我应该在一次选择后提交

时间:2012-11-08 11:02:25

标签: mysql mysql-python

我使用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(...),以确保该操作未在连接上留下未完成的交易吗?

1 个答案:

答案 0 :(得分:11)

您需要考虑以下两点:

  1. 有效的隔离级别
  2. 您希望在交易中“看到”的状态
  3. MySQL中的默认隔离级别为REPEATABLE READ,这意味着如果在事务内部运行SELECT两次,即使其他事务已提交更改,您也会看到完全相同的数据。

    大多数时候,人们希望在运行第二个select语句时看到提交的更改 - 这是READ COMMITTED隔离级别的行为。

    如果您没有更改MySQL中的默认级别,并且执行期望在同一事务中运行SELECT两次时看到数据库中的更改 - 那么您无法在“相同”的交易,您需要提交第一个SELECT声明。

    如果您实际上想要在事务中查看数据的一致状态,那么您应该提交。

      

    然后几分钟后,第一个进程执行一个事务性操作并尝试提交。这个提交会失败吗?

    这完全取决于您对“是交易”的定义。你在关系数据库中做的任何事情都是“事务性的”(实际上对于MySQL来说并不完全正确,但是为了论证,如果你只使用InnoDB作为你的存储引擎,你可以假设这一点)。

    如果“第一个进程”仅选择数据(即“只读事务”),那么当然提交将起作用。如果它试图修改另一个事务已经提交的数据并且 正在运行REPEATABLE READ,则可能会出现错误(等待任何锁定释放后)。在这种情况下,我不是100%关于MySQL的行为。

    您应该使用您喜欢的SQL客户端通过两个不同的会话手动尝试此操作来了解该行为。也要改变你的隔离级别,以便看到不同级别的效果。