@skipIf(threading is None, "Test requires threading")
    def test_implicit_savepoint_rollback(self):

        other_thread_ready = threading.Event()

        def other_thread():
            try:
                with transaction.atomic():
                    Reporter.objects.create(id=1, first_name="Tintin")
                    other_thread_ready.set()
                    # We cannot synchronize the two threads with an event here
                    # because the main thread locks. Sleep for a little while.
                    time.sleep(1)
                    # 2) ... and this line deadlocks. (see below for 1)
                    Reporter.objects.exclude(id=1).update(id=2)
            finally:
                # This is the thread-local connection, not the main connection.
                connection.close()

        other_thread = threading.Thread(target=other_thread)
        other_thread.start()
        other_thread_ready.wait()

        with six.assertRaisesRegex(self, OperationalError, 'Deadlock found'):
            # Double atomic to enter a transaction and create a savepoint.
            with transaction.atomic():
                with transaction.atomic():
                    # 1) This line locks... (see above for 2)
                    Reporter.objects.create(id=1, first_name="Tintin")

        other_thread.join()
MySQL implicitly rolls back savepoints when it deadlocks (#22291).
dataset/ETHPy150Open cloudera/hue/desktop/core/ext-py/Django-1.6.10/tests/transactions/tests.py/AtomicMySQLTests.test_implicit_savepoint_rollback