Reputation: 12521
I'm looking at upgrading a Django-based site from v1.4 to v1.9 of the framework. The site performs a critical role in our infrastructure and sees considerable traffic. Our test suite is pretty good, but nowhere near 100% coverage. Because of all this, I'd like to perform the upgrade in a safe and conservative fashion.
I'm inspired by Github's recent approach to rewriting major features by running the new code and old code as experiment and control, returning the result of the old code and logging any differences or errors in the new code.
Because I'm upgrading the framework version itself (along with supporting libraries), I can't just use a Python port of Scientist, like laboratory. It seems to me that the simplest way to do this would be to fork the site itself, send every request to both sites, but only commit and return the result from the control site.
To that end, I would need the experiment site to run against the same database as the control site, but make no commits. It seems to me I should be able to do this by writing some sort of middleware that rolls back the current transaction at the end of the request-response cycle, but I'm not exactly sure how to go about this.
So, my question: how can I roll back every transaction for every request to a Django 1.9 site?
UPDATE:
With a bit more research, it seems like I could get this behavior by enabling ATOMIC_REQUESTS
(best setting name ever!) for the database and using custom middleware with a process_response()
method that rolls back the transaction. I'd welcome refinements or alternatives.
Upvotes: 0
Views: 476
Reputation: 10256
If you want to use @transaction.atomic
and still manage the exception, you can use it with with
statement:
try:
with transaction.atomic():
a.save()
except IntegrityError, e:
return .... # Manage the response
Upvotes: 1
Reputation: 1449
you should use annotation @transaction.atomic()
like
The first option is to roll back the entire transaction. For example::
a.save() # Succeeds, but may be undone by transaction rollback
try:
b.save() # Could throw exception
except IntegrityError:
transaction.rollback()
c.save() # Succeeds, but a.save() may have been undone
Calling transaction.rollback()
rolls back the entire transaction. Any
uncommitted database operations will be lost. In this example, the changes
made by a.save()
would be lost, even though that operation raised no error
itself.
for better understanding just check transaction
Upvotes: 2