Code

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#15383 closed (invalid)

TransactionManagementError although I've rollbacked the transaction

Reported by: coopkont@… Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: transaction
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description (last modified by russellm)

Hi,

This bug must be very recent, as my piece of code that is now blowing used to work.
The problem is when a function has the @transaction.commit_manually and it calls another function after it rolls back.

Example

@transaction.commit_manually
def example(request):
    transaction.rollback()
    another_func()

If the proc returns an HttpResponse or a redirect or whatever after the rollback this works fine. Trying to debug the django code I've realized that the transaction rollbacks fine and the connection is set to _dirty=False. But as soon as another function is called the connection is flagged to dirty again. Now even if the function called does not have the decorator the connection will be set to dirty.

Not sure at all if the expected behavior is to set the connection to dirty but it looks to me like it's causing this issue since the following code checks that variable and just throws an error:

 def leave_transaction_management(self):
        """
        Leaves transaction management for a running thread. A dirty flag is carried
        over to the surrounding block, as a commit will commit all changes, even
        those from outside. (Commits are on connection level.)
        """
        self._leave_transaction_management(self.is_managed())
        if self.transaction_state:
            del self.transaction_state[-1]
        else:
            raise TransactionManagementError("This code isn't under transaction "
                "management")
        if self._dirty:
            self.rollback()
            raise TransactionManagementError("Transaction managed block ended with "
                "pending COMMIT/ROLLBACK")
        self._dirty = False

This is on the trunk version 1.3 beta 1 SVN-15632

This is my stack trace:

Unexpected error in request /register/ : Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/usr/lib/python2.6/dist-packages/django/db/transaction.py", line 223, in inner
    self.__exit__(None, None, None)
  File "/usr/lib/python2.6/dist-packages/django/db/transaction.py", line 208, in __exit__
    self.exiting(exc_value, self.using)
  File "/usr/lib/python2.6/dist-packages/django/db/transaction.py", line 303, in exiting
    leave_transaction_management(using=using)
  File "/usr/lib/python2.6/dist-packages/django/db/transaction.py", line 56, in leave_transaction_management
    connection.leave_transaction_management()
  File "/usr/lib/python2.6/dist-packages/django/db/backends/__init__.py", line 115, in leave_transaction_management
    raise TransactionManagementError("Transaction managed block ended with "
TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK

Attachments (0)

Change History (5)

comment:1 Changed 3 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

Firstly -- please use preview when submitting a bug.

Secondly -- Yes, this is a recent change. It was introduced in r15492 to address #9964. This change and it's implications is listed in the release notes.

comment:2 Changed 3 years ago by russellm

  • Description modified (diff)

comment:3 Changed 3 years ago by anonymous

Are you happy with this change ?
I am really really sorry but I refuse to believe that this is a feature instead of a bug.
What about custom tags in templates that run select queries in the db ? What about display logic that is implemented after the transactional part of a request is finished ?
I wasn't even aware that the transaction persists for the whole connection, I thought that the transaction was committed/rollbacked when the actual commands are called. This it self is really bad as it probably leaves the transaction open for longer than needed, locking tables throughout the whole request !

I do appreciate that this is a documented change but it completely makes transaction management in django unusable. I will seek advice in the forums !

comment:4 Changed 3 years ago by russellm

Yes, we're happy with the change. The change was made for a very good reason. Read the history of the ticket if you want to know what those reasons are.

comment:5 Changed 3 years ago by jacob

  • milestone 1.3 deleted

Milestone 1.3 deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.