我应该在单次选择后提交吗

Posted

技术标签:

【中文标题】我应该在单次选择后提交吗【英文标题】:Should I commit after a single select 【发布时间】:2012-10-28 13:45:28 【问题描述】:

我正在使用 mysqldb 模块从 python 处理 MySQL 5.0。

考虑一个简单的函数来加载和返回整个数据库表的内容:

def load_items(connection):
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM MyTable")
    return cursor.fetchall()

此查询旨在进行简单的数据加载,除了单个 SELECT 语句之外没有任何事务行为。

运行此查询后,可能需要一段时间才能再次使用同一连接执行其他任务,但同时其他连接仍可在数据库上运行。

我是否应该在cursor.execute(...) 调用之后立即调用connection.commit() 以确保该操作没有在连接上留下未完成的事务?

【问题讨论】:

【参考方案1】:

您需要考虑以下两点:

    有效的隔离级别 您希望在交易中“看到”什么样的状态

MySQL 中的默认隔离级别是REPEATABLE READ,这意味着如果您在一个事务中运行两次SELECT,即使其他事务已提交更改,您也会看到完全相同的数据。

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

如果您没有更改 MySQL 中的默认级别,并且您确实希望在同一事务中运行 SELECT 两次时看到数据库中的更改 - 那么您不能在“相同”事务,您需要提交您的第一个 SELECT 语句。

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

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

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

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

您真的应该使用您最喜欢的 SQL 客户端在两个不同的会话中手动尝试此操作,以了解行为。请务必更改您的隔离级别,以查看不同级别的效果。

【讨论】:

我想我的意思是,如果在使用相同的连接(或任何其他连接)调用 load_items 后执行任何操作,我不希望调用 @987654327 @ 被视为同一事务的一部分。现在我已经阅读了您的答案并以这种方式提出了我的问题,很明显我正在寻找的行为是在SELECT 之后调用commit。谢谢。 哦,您的最后建议是一个很好的建议,谢谢。这是我发布问题后一直在做的事情:D 甲骨文呢?

以上是关于我应该在单次选择后提交吗的主要内容,如果未能解决你的问题,请参考以下文章

回复元数据拒绝后,我应该重新提交二进制文件吗?

如何自动加载最后一次提交(单次提交)?

javascript提交

为啥我提交后没有显示我的数据?我没看出有啥不对吗?

我应该在提交表单后使用 301、302 还是 303 重定向?

30日前提交证据包括30日当日吗?