From b1f70d9e53f4256cf82594a1a44428d8e64cb23d Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Wed, 3 Jun 2009 03:18:48 +0000 Subject: [PATCH] [soc2009/multidb] Updated the transaction decorators for use with multiple DB. git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@10911 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/comments/models.py | 4 +- django/core/management/commands/sqlindexes.py | 1 + django/core/management/commands/sqlreset.py | 1 + .../management/commands/sqlsequencereset.py | 1 + django/db/transaction.py | 93 +++++++++++-------- 5 files changed, 61 insertions(+), 39 deletions(-) diff --git a/django/contrib/comments/models.py b/django/contrib/comments/models.py index 7dd4f81a4c..f8891846fe 100644 --- a/django/contrib/comments/models.py +++ b/django/contrib/comments/models.py @@ -79,10 +79,10 @@ class Comment(BaseCommentAbstractModel): def __unicode__(self): return "%s: %s..." % (self.name, self.comment[:50]) - def save(self, force_insert=False, force_update=False): + def save(self, *args, **kwargs): if self.submit_date is None: self.submit_date = datetime.datetime.now() - super(Comment, self).save(force_insert, force_update) + super(Comment, self).save(*args, **kwargs) def _get_userinfo(self): """ diff --git a/django/core/management/commands/sqlindexes.py b/django/core/management/commands/sqlindexes.py index fad0b4f8f7..9e6b3e384c 100644 --- a/django/core/management/commands/sqlindexes.py +++ b/django/core/management/commands/sqlindexes.py @@ -11,6 +11,7 @@ class Command(AppCommand): make_option('--database', action='store', dest='database', default='default', help='Nominates a database to print the SQL ' 'for. Defaults to the "default" database.'), + ) output_transaction = True diff --git a/django/core/management/commands/sqlreset.py b/django/core/management/commands/sqlreset.py index 66d7e56280..fc77df6734 100644 --- a/django/core/management/commands/sqlreset.py +++ b/django/core/management/commands/sqlreset.py @@ -11,6 +11,7 @@ class Command(AppCommand): make_option('--database', action='store', dest='database', default='default', help='Nominates a database to print the SQL ' 'for. Defaults to the "default" database.'), + ) output_transaction = True diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index a1bbf48f5b..4aa2979a91 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -10,6 +10,7 @@ class Command(AppCommand): make_option('--database', action='store', dest='database', default='default', help='Nominates a database to print the SQL ' 'for. Defaults to the "default" database.'), + ) output_transaction = True diff --git a/django/db/transaction.py b/django/db/transaction.py index 39aaab4482..be5e0e4293 100644 --- a/django/db/transaction.py +++ b/django/db/transaction.py @@ -20,7 +20,7 @@ try: from functools import wraps except ImportError: from django.utils.functional import wraps # Python 2.3, 2.4 fallback. -from django.db import connections +from django.db import connections, DEFAULT_DB_ALIAS from django.conf import settings class TransactionManagementError(Exception): @@ -259,60 +259,79 @@ def savepoint_commit(sid, using=None): # TODO update all of these for multi-db -def autocommit(func): +def autocommit(using_or_func=None): """ Decorator that activates commit on save. This is Django's default behavior; this decorator is useful if you globally activated transaction management in your settings file and want the default behavior in some view functions. """ - def _autocommit(*args, **kw): - try: - enter_transaction_management(managed=False) - managed(False) - return func(*args, **kw) - finally: - leave_transaction_management() - return wraps(func)(_autocommit) + def inner_autocommit(func, using=None): + def _autocommit(*args, **kw): + try: + enter_transaction_management(managed=False, using=using) + managed(False, using=using) + return func(*args, **kw) + finally: + leave_transaction_management(using=using) + return wraps(func)(_autocommit) + if using_or_func is None: + using_or_func = DEFAULT_DB_ALIAS + if callable(using_or_func): + return inner_autocommit(using_or_func, DEFAULT_DB_ALIAS) + return lambda func: inner_autocommit(func, using_or_func) -def commit_on_success(func): + +def commit_on_success(func_or_using=None): """ This decorator activates commit on response. This way, if the view function runs successfully, a commit is made; if the viewfunc produces an exception, a rollback is made. This is one of the most common ways to do transaction control in web apps. """ - def _commit_on_success(*args, **kw): - try: - enter_transaction_management() - managed(True) + def inner_commit_on_success(func, using=None): + def _commit_on_success(*args, **kw): try: - res = func(*args, **kw) - except: - # All exceptions must be handled here (even string ones). - if is_dirty(): - rollback() - raise - else: - if is_dirty(): - commit() - return res - finally: - leave_transaction_management() - return wraps(func)(_commit_on_success) + enter_transaction_management(using=using) + managed(True, using=using) + try: + res = func(*args, **kw) + except: + # All exceptions must be handled here (even string ones). + if is_dirty(using=using): + rollback(using=using) + raise + else: + if is_dirty(using=using): + commit(using=using) + return res + finally: + leave_transaction_management(using=using) + return wraps(func)(_commit_on_success) + if func_or_using is None: + func_or_using = DEFAULT_DB_ALIAS + if callable(func_or_using): + return inner_commit_on_success(func_or_using, DEFAULT_DB_ALIAS) + return lambda func: inner_commit_on_success(func, func_or_using) -def commit_manually(func): +def commit_manually(func_or_using=None): """ Decorator that activates manual transaction control. It just disables automatic transaction control and doesn't do any commit/rollback of its own -- it's up to the user to call the commit and rollback functions themselves. """ - def _commit_manually(*args, **kw): - try: - enter_transaction_management() - managed(True) - return func(*args, **kw) - finally: - leave_transaction_management() + def inner_commit_manually(func, using=None): + def _commit_manually(*args, **kw): + try: + enter_transaction_management(using=using) + managed(True, using=using) + return func(*args, **kw) + finally: + leave_transaction_management(using=using) - return wraps(func)(_commit_manually) + return wraps(func)(_commit_manually) + if func_or_using is None: + func_or_using = DEFALUT_DB_ALIAS + if callable(func_or_using): + return inner_commit_manually(func_or_using, DEFAULT_DB_ALIAS) + return lambda func: inner_commit_manually(func, func_or_using)