Python Django中的游标是否在打开的事务中运行?
我的Django应用程序正在使用一些自定义SQL,我正在这样的视图中执行这些SQL:Python Django中的游标是否在打开的事务中运行?,python,sql,django,postgresql,python-db-api,Python,Sql,Django,Postgresql,Python Db Api,我的Django应用程序正在使用一些自定义SQL,我正在这样的视图中执行这些SQL: db = router.db_for_write(model) cursor = connections[db].cursor() cursor.execute("INSERT INTO ....") 由于我使用的是TransactionMiddleware,因此我的视图在事务内部运行,但我不清楚获得这样的新游标是“转义”当前打开的事务,还是游标仍然是打开的事务的一部分。我收到一些错误消息,使我相信游标正在事
db = router.db_for_write(model)
cursor = connections[db].cursor()
cursor.execute("INSERT INTO ....")
由于我使用的是TransactionMiddleware
,因此我的视图在事务内部运行,但我不清楚获得这样的新游标是“转义”当前打开的事务,还是游标仍然是打开的事务的一部分。我收到一些错误消息,使我相信游标正在事务内部运行
我希望能够使用游标在由TransactionMiddleware
打开的事务之外执行SQL命令。这可能吗
如果重要的话,我正在用PostgreSQL 8.4数据库运行Django 1.4。如果有一个视图需要手动管理事务,那么应该在该视图中使用decorator手动提交 从
是的,导入事务游标只提供事务的游标,而不创建新事务。我相信您需要一个单独的db连接来获得一个单独的、同时进行的事务。我也非常确定django每个数据库只管理一个连接。但你可以创建另一个。也许有一些很好的理由不这样做。我想到了复杂性 我认为这样做是可行的:
from django.conf import settings
from django.db.utils import ConnectionHandler
def my_view(request):
"""Flirt with complexity by using two connections to db"""
private_connections = ConnectionHandler(settings.DATABASES)
db = router.db_for_write(model)
new_conn = private_connections[db]
new_conn.enter_transaction_management()
new_conn.managed(True)
new_cur = new_conn.cursor()
new_cur.execute("INSERT INTO ...")
new_conn.commit()
new_conn.close()
请注意,您不能使用django.db.transaction
,因为它在django.db.connections
中的全局连接实例上运行,但在任何情况下,这只是连接对象上事务管理方法的一个薄包装
我想真正的问题是你为什么要这么做Lakshman Prasad的回答有什么问题?您可以随时提交/回滚,因此没有任何东西可以阻止您在单个视图中的不同事务中执行不同的任务。这些事务必须是并行的,而不是连续的,这一事实暗示了它们之间存在某种逻辑联系,在我看来,这表明它们实际上应该在同一个事务中
如果另一方面,你只是试图模拟某种脱机处理,其成功或失败与视图并不特别相关,请考虑设置消息队列并在单独的进程中执行这些插入。这是一个很受欢迎的软件包。然而,如果响应时间不是一个主要问题,我仍然认为连续的事务应该足够了
更新: 如果您希望数据库支持的缓存在自动提交模式下运行,同时仍在单个(单独)事务中运行业务逻辑,那么有一种django方法。您需要做的就是确保缓存发生在commit\u on\u success
之外:
- 如果您只是在使用缓存中间件,请确保它位于
之外TransactionMiddleware
- 如果您使用缓存视图装饰器,我大胆猜测您可以禁用
(或者将问题视图放在TransactionMiddleware
装饰器中),并在缓存装饰器中使用自动提交
装饰器。这看起来很有趣,但我不知道为什么不起作用:提交成功
@transaction.autocommit @cache_page(500) @transaction.commit_on_success def my_view(request): "..."
- 如果使用模板缓存或执行更复杂的手动缓存,还可以禁用
(或将问题视图放在TransactionMiddleware
装饰器中),并使用自动提交
作为上下文管理器,只在托管事务中放置所需的代码,将视图的其余部分保留在自动提交中提交成功
@transaction.autocommit def my_view(request): data = cache.get(some_key) with transaction.commit_on_success(): context = do_some_processing(data) cache.set(some_key, context['data']) return render('template/with/cache/blocks.html', context=context)
@transaction.autocommit
def my_view(request):
data = cache.get(some_key)
with transaction.commit_on_success():
context = do_some_processing(data)
cache.set(some_key, context['data'])
return render('template/with/cache/blocks.html', context=context)