Django ORM 如何检测代码是否在事务中执行?psycopg2 可直接检测吗?
Django 原生事务状态检测方案
Django ORM 本身内置了对应的能力,无需依赖底层数据库驱动即可实现需求,你要的inside_transaction函数可以直接按如下方式实现:
from django.db import transaction def inside_transaction(using=None): # using 为可选参数,用于指定要检测的数据库连接别名,默认为 default 库 return transaction.get_connection(using=using).in_atomic_block
你给出的测试代码可以直接正常运行:
with transaction.atomic(): assert inside_transaction() == True assert inside_transaction() == False
in_atomic_block是Django数据库连接对象的原生属性,会自动跟踪atomic()上下文的嵌套层级,只要当前处于任意层级的事务上下文中就会返回True,兼容Django支持的所有数据库后端。
基于psycopg2的底层实现方案
如果你需要绕过Django ORM层,直接通过PostgreSQL驱动psycopg2做检测,也可以按如下方式实现,该方法仅适用于PostgreSQL数据库:
from django.db import transaction def inside_transaction_psycopg2(using=None): # 获取Django封装的连接对象 dj_conn = transaction.get_connection(using=using) # 确保连接已初始化 if not dj_conn.is_usable(): dj_conn.connect() # 获取psycopg2原生连接对象 psycopg2_conn = dj_conn.connection # 事务状态为0(TRANSACTION_STATUS_IDLE)表示未处于事务中 return psycopg2_conn.get_transaction_status() != 0
注意事项
- 优先使用Django原生的
in_atomic_block方案,兼容性更强,可正确处理嵌套事务、多数据库等场景 - psycopg2方案仅支持PostgreSQL数据库,无法适配MySQL、SQLite等其他Django支持的数据库
内容的提问来源于stack exchange,提问作者Ken Kinder
相关产品推荐
相关产品推荐

