Re: always rollback decorator

2008-09-09 Thread Malcolm Tredinnick


On Tue, 2008-09-09 at 10:35 +0200, Thomas Guettler wrote:
[...]
> I use Postgres supports nested transaction by using savepoints.
> 
> Unfortunately I can't get it working: I try to use savepoints, but they 
> get lost
> as soon is the commit_on_success decorator sends COMMIT.

That's how savepoints work, yes. They're not exactly the same as nested
transactions, since the transaction overrides everything. Savepoints
give you saved points within a transaction, but not more than that.

> I guess I need to convert all commit_on_success decorators to
> a new commit_on_success_unless_inside_transaction decorator.
> 
> Any idea how to solve this?

Write a new database backend that inherits pretty much everything from
the postgresql backend, but overrides the _commit and _rollback methods
of the BaseDatabaseOperations class. Then use that backend for your
tests.

Regards,
Malcolm



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---



always rollback decorator

2008-09-09 Thread Thomas Guettler
Hi,

I try to write an always_rollback decorator like the commit_on_success 
one. I want
to use it to test a live system without changing it.

I use Postgres supports nested transaction by using savepoints.

Unfortunately I can't get it working: I try to use savepoints, but they 
get lost
as soon is the commit_on_success decorator sends COMMIT.

I guess I need to convert all commit_on_success decorators to
a new commit_on_success_unless_inside_transaction decorator.

Any idea how to solve this?

 Thomas

-- 
Thomas Guettler, http://www.thomas-guettler.de/
E-Mail: guettli (*) thomas-guettler + de


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---

try:
from functools import wraps
except ImportError:
from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.

# Django
from django.contrib.auth.models import User
from django.db import transaction

magic='this value should not persist'

def always_rollback(func):
"""
Based on commit_on_success of django
"""
def _always_rollback(*args, **kw):
try:
transaction.enter_transaction_management()
transaction.managed(True)
sid=transaction.savepoint()
try:
res = func(*args, **kw)
finally:
transaction.savepoint_rollback(sid)
transaction.rollback()
return res
finally:
transaction.leave_transaction_management()
return wraps(func)(_always_rollback)

@transaction.commit_on_success
def set_something():
user=User.objects.get(id=1)
user.first_name='this value should not persist'
user.save()

@always_rollback
def pretend_to_set():
set_something()

def main():
user=User.objects.get(id=1)
user.first_name='start'
user.save()
pretend_to_set()
user=User.objects.get(id=1)
if user.first_name=='start':
print 'always rollback succeeded'
elif user.first_name==magic:
print 'always rollback failed'
else:
raise Exception()

if __name__=='__main__':
main()