Creo que necesitaría una conexión db separada para obtener una transacción simultánea por separado. También estoy bastante seguro de que Django administra solo una conexión por base de datos. Pero podrías crear otro. Puede haber alguna buena razón para no hacer esto. La complejidad viene a la mente.
Creo que algo como esto funcionaría:
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()
Tenga en cuenta que no puede usar django.db.transaction
porque opera en las instancias de conexión global en django.db.connections
, pero en cualquier caso, eso es solo una envoltura delgada alrededor de los métodos de administración de transacciones en el objeto de conexión.
Supongo que la verdadera pregunta es ¿por qué quieres hacer esto? ¿Y qué tiene de malo la respuesta de Lakshman Prasad? Puede confirmar/retroceder cuando lo desee, por lo que no hay nada que le impida realizar diferentes tareas en distintas transacciones dentro de una sola vista. El hecho de que las transacciones deban ser paralelas y no sucesivas sugiere alguna conexión lógica entre ellas, lo que en mi opinión indicaría que realmente deberían estar en la misma transacción.
Si, por otro lado, solo está tratando de emular algún tipo de procesamiento fuera de línea, cuyo éxito o fracaso no es particularmente relevante para la vista, considere configurar una cola de mensajes y realizar estas inserciones en un lugar separado. proceso. Apio es un paquete popular para hacer precisamente eso. Sin embargo, si el tiempo de respuesta no es una preocupación importante, sigo pensando que las transacciones sucesivas deberían ser suficientes.
Actualización:
Si desea que su caché respaldada por la base de datos funcione en modo de confirmación automática mientras aún ejecuta su lógica comercial en una sola transacción (separada), hay una forma de django. Todo lo que necesita hacer es asegurarse de que el almacenamiento en caché ocurra fuera el commit_on_success
:
-
Si solo está utilizando el middleware de almacenamiento en caché, asegúrese de que esté fuera del
TransactionMiddleware
. -
Si usa decoradores de vista de almacenamiento en caché, me aventuraría a suponer que podría deshabilitar
TransactionMiddleware
(o coloque la vista del problema dentro de unautocommit
decorador) y use elcommit_on_success
decorador interior el decorador de almacenamiento en caché. Parece divertido, pero no sé por qué no funcionaría:@transaction.autocommit @cache_page(500) @transaction.commit_on_success def my_view(request): "..."
-
Si usa el almacenamiento en caché de plantillas o hace un almacenamiento en caché manual más complicado, también puede deshabilitar
TransactionMiddleware
(o coloque la vista del problema dentro de unautocommit
decorador) y usecommit_on_success
como administrador de contexto para poner solo el código que necesita en una transacción administrada, dejando el resto de la vista en confirmación automática.@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)