FastAPI+SQLAlchemy:只读操作是否会自动创建事务?
SQLAlchemy 只读操作与事务处理答疑
问题1:只读操作是否不会创建事务?
SQLAlchemy的Session默认会在**首次执行任何数据库操作(包括SELECT查询)**时隐式启动事务。官方文档提到的“虚拟事务”是指Session的延迟事务创建机制——不会在Session初始化时就创建事务,而是等到真正需要和数据库交互时才触发,但只要执行了SELECT这类操作,事务就会被创建。所以只读操作同样会启动事务。
问题2:SQLAlchemy中对应Spring @Transactional(readOnly = true)的方案,是否支持完全不启动事务的只读操作?
SQLAlchemy没有和Spring该注解完全对等的配置,但可以通过两种方式适配只读场景:
- 数据库层面的只读优化:给Session的连接设置只读执行选项,部分数据库(如PostgreSQL、MySQL)会识别该参数,既优化查询性能,又能禁止写操作:
with session.connection(execution_options={"readonly": True}): result = session.execute(select(MyModel)).fetchall() - 完全跳过事务(直接用Engine):如果要彻底避免事务,可以绕过Session,直接使用Engine执行查询。此时连接默认处于自动提交模式,单条SELECT操作不会启动显式事务(取决于数据库默认行为,多数数据库在自动提交下的单SELECT不会创建事务):
from sqlalchemy import create_engine, select from models import MyModel engine = create_engine("your-db-url") with engine.connect() as conn: result = conn.execute(select(MyModel)).fetchall()
问题3:session.execute(select(...))是否会隐式创建事务?
是的,只要通过Session执行session.execute(select(...))这类数据库操作,Session就会隐式启动事务。Session的设计核心是围绕事务上下文来管理实体状态,所以所有通过Session发起的数据库交互都会处于事务中。如果要避免这种“不必要”的事务,推荐使用上述直接通过Engine执行查询的方式;如果仍需使用Session,可通过设置连接的只读执行选项来优化,而非完全取消事务(Session依赖事务上下文工作)。
内容的提问来源于stack exchange,提问作者김완영
相关产品推荐
相关产品推荐

