SELECT语句是否会启动事务?

7 投票
2 回答
2299 浏览
提问于 2025-04-17 10:04

我在文档中看到:

...因为当一个游标执行查询时,事务就开始了,但只有当连接对象执行COMMIT或ROLLBACK时,事务才结束。

import MySQLdb

db = MySQLdb.connect(user="root", db="test")
c = db.cursor()
c.execute("SELECT * FROM books")
print c.fetchall()

我怀疑MySQLdb在执行一些不修改数据的查询(比如SELECT)时也会开始一个事务,因为很难判断一个查询是否只是读取数据而不写入。

  1. 这是真的吗?
  2. 如果是真的,这意味着我在每次查询后都应该执行cursor.commit(),以确保没有表被锁住吗?
  3. 还有其他我不知道的问题吗?

谢谢

2 个回答

2
  1. 这是真的,但它在每次查询后也会自动提交,因为MySQL客户端默认是autocommit=1

  2. 你不应该这样做,因为SELECT语句执行后不会持有任何锁。在实际操作中,手动提交可能会导致显著的性能下降。

  3. 这可能会有用:为什么Python的DB-API中的连接没有“开始”操作?

3

是的,SELECT 语句和其他语句一样,会开始一个事务。

如果你想避免这种情况,可以尝试这样做:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM books ;
COMMIT ;

具体来说:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;

这段话的意思是,接下来的指令可以读取那些已经被修改但还没有被 COMMIT 的行。这样的事务不会获得独占锁。

第二部分 SELECT * FROM books ; 显然是一个 SQL 语句,而第三部分 COMMIT ; 则是结束事务并让它“永久生效”。在这种情况下,没有进行任何写入,所以 COMMIT 只是用来结束事务的。

撰写回答