def test_fake_nesting_commit(self): barrier = Event() threadIds = [] @transaction @inlineCallbacks def trans1(txn): threadIds.append(threadable.getThreadID()) yield Transaction(name="TEST1").save() @transaction @inlineCallbacks def trans2(txn): threadIds.append(threadable.getThreadID()) yield trans1() yield Transaction(name="TEST2").save() barrier.wait() # wait here to delay commit d = trans2() count = yield Transaction.count() self.assertEqual(count, 0) barrier.set() yield d self.assertEqual(threadIds[0], threadIds[1], "Nested transactions don't run in same thread") count = yield Transaction.count() self.assertEqual(count, 2)
def test_fake_nesting_rollback(self): barrier = Event() @transaction @inlineCallbacks def trans1(txn): yield Transaction(name="TEST1").save() txn.rollback() # should propagate to the root transaction @transaction @inlineCallbacks def trans2(txn): yield Transaction(name="TEST2").save() yield trans1() barrier.wait() # wait here to delay commit d = trans2() count = yield Transaction.count() self.assertEqual(count, 0) barrier.set() yield d count = yield Transaction.count() self.assertEqual(count, 0)
def test_commit(self): barrier = Event() @transaction @inlineCallbacks def trans(txn): self.assertFalse(threadable.isInIOThread(), "Transactions must not run in main thread") yield Transaction(name="TEST1").save() yield Transaction(name="TEST2").save() barrier.wait() # wait here to delay commit returnValue("return value") d = trans() count = yield Transaction.count() self.assertEqual(count, 0) barrier.set() res = yield d self.assertEqual(res, "return value") count = yield Transaction.count() self.assertEqual(count, 2)
def trans(txn): self.assertFalse(threadable.isInIOThread(), "Transactions must not run in main thread") yield Transaction(name="TEST1").save() yield Transaction(name="TEST2").save() barrier.wait() # wait here to delay commit returnValue("return value")
def test_parallel_transactions(self): if DBTYPE == "sqlite": raise unittest.SkipTest( "Parallel connections are not supported by sqlite") threadIds = [] # trans1 is supposed to pass, trans2 is supposed to fail due to unique constraint # regarding synchronization: trans1 has to start INSERT before trans2, # because otherwise it would wait for trans2 to finish due to postgres synchronization strategy on_trans1_insert = Event() barrier1, barrier2 = Event(), Event() @transaction @inlineCallbacks def trans1(txn): threadIds.append(threadable.getThreadID()) yield Transaction(name="TEST1").save() on_trans1_insert.set() barrier1.wait() # wait here to delay commit) @transaction @inlineCallbacks def trans2(txn): threadIds.append(threadable.getThreadID()) on_trans1_insert.wait() yield Transaction(name="TEST1").save() barrier2.wait() # wait here to delay commit d1 = trans1() d2 = trans2() # commit tran1, should pass: barrier1.set() yield d1 count = yield Transaction.count() self.assertEqual(count, 1) # commit trans2: barrier2.set() # should fail due to unique constraint violation yield self._assertRaises(d2, Exception) self.assertNotEqual( threadIds[0], threadIds[1], "Parallel transactions don't run in different threads") count = yield Transaction.count() self.assertEqual(count, 1)
def test_parallel_transactions(self): if DBTYPE == "sqlite": raise unittest.SkipTest("Parallel connections are not supported by sqlite") threadIds = [] # trans1 is supposed to pass, trans2 is supposed to fail due to unique constraint # regarding synchronization: trans1 has to start INSERT before trans2, # because otherwise it would wait for trans2 to finish due to postgres synchronization strategy on_trans1_insert = Event() barrier1, barrier2 = Event(), Event() @transaction @inlineCallbacks def trans1(txn): threadIds.append(threadable.getThreadID()) yield Transaction(name="TEST1").save() on_trans1_insert.set() barrier1.wait() # wait here to delay commit) @transaction @inlineCallbacks def trans2(txn): threadIds.append(threadable.getThreadID()) on_trans1_insert.wait() yield Transaction(name="TEST1").save() barrier2.wait() # wait here to delay commit d1 = trans1() d2 = trans2() # commit tran1, should pass: barrier1.set() yield d1 count = yield Transaction.count() self.assertEqual(count, 1) # commit trans2: barrier2.set() # should fail due to unique constraint violation yield self._assertRaises(d2, Exception) self.assertNotEqual(threadIds[0], threadIds[1], "Parallel transactions don't run in different threads") count = yield Transaction.count() self.assertEqual(count, 1)
def test_savepoints_mixed(self): if DBTYPE == "sqlite": raise unittest.SkipTest( "SAVEPOINT acts weird with sqlite, needs further inspection.") @nested_transaction @inlineCallbacks def trans1(txn): yield Transaction(name="TEST3").save() with transaction() as txn2: yield Transaction(name="TEST4").save() txn2.rollback() @transaction @inlineCallbacks def trans2(txn): yield Transaction(name="TEST1").save() with nested_transaction(): yield Transaction(name="TEST2").save() yield trans1() yield Transaction(name="TEST5").save() yield trans2() objects = yield Transaction.all() self.assertEqual([obj.name for obj in objects], ["TEST1", "TEST2", "TEST5"])
def test_parallel_massive(self): # Make sure that everything works alright even when starting a massive amount of parallel transactions if DBTYPE == "sqlite": raise unittest.SkipTest( "Parallel connections are not supported by sqlite") N = 100 @transaction @inlineCallbacks def trans(txn, i): yield Transaction(name=str(i)).save() if i % 2 == 1: txn.rollback() else: txn.commit() deferreds = [trans(i) for i in range(N)] results = yield DeferredList(deferreds) self.assertTrue(all(success for success, result in results)) objects = yield Transaction.all() actual = sorted(int(obj.name) for obj in objects) actual = [str(i) for i in actual] expected = [str(i) for i in range(0, N, 2)] self.assertEquals(actual, expected)
def test_parallel_massive(self): # Make sure that everything works alright even when starting a massive amount of parallel transactions if DBTYPE == "sqlite": raise unittest.SkipTest("Parallel connections are not supported by sqlite") N = 100 @transaction @inlineCallbacks def trans(txn, i): yield Transaction(name=str(i)).save() if i % 2 == 1: txn.rollback() else: txn.commit() deferreds = [trans(i) for i in range(N)] results = yield DeferredList(deferreds) self.assertTrue(all(success for success, result in results)) objects = yield Transaction.all() actual = sorted(int(obj.name) for obj in objects) actual = [str(i) for i in actual] expected = [str(i) for i in range(0, N, 2)] self.assertEquals(actual, expected)
def test_fake_nesting_ctxmgr(self): @transaction @inlineCallbacks def trans1(txn): yield Transaction(name="TEST1").save() with transaction() as txn2: yield Transaction(name="TEST2").save() txn2.rollback() yield trans1() count = yield Transaction.count() self.assertEqual(count, 0)
def test_savepoints_commit(self): if DBTYPE == "sqlite": raise unittest.SkipTest("SAVEPOINT acts weird with sqlite, needs further inspection.") @transaction @inlineCallbacks def trans1(txn): yield Transaction(name="TEST1").save() with nested_transaction(): yield Transaction(name="TEST2").save() yield Transaction(name="TEST3").save() yield trans1() objects = yield Transaction.all() self.assertEqual([obj.name for obj in objects], ["TEST1", "TEST2", "TEST3"])
def test_rollback(self): barrier = Event() @transaction @inlineCallbacks def trans(txn): yield Transaction(name="TEST1").save() yield Transaction(name="TEST2").save() barrier.wait() # wait here to delay commit raise ZeroDivisionError() d = trans() barrier.set() yield self._assertRaises(d, ZeroDivisionError) count = yield Transaction.count() self.assertEqual(count, 0)
def trans1(txn): yield Transaction(name="TEST3").save() with transaction() as txn2: yield Transaction(name="TEST4").save() txn2.rollback()
def trans2(txn): threadIds.append(threadable.getThreadID()) yield trans1() yield Transaction(name="TEST2").save() barrier.wait() # wait here to delay commit
def trans1(txn): yield Transaction(name="TEST1").save() txn.rollback() # should propagate to the root transaction
def trans2(txn): yield Transaction(name="TEST2").save() yield trans1() barrier.wait() # wait here to delay commit
def trans2(txn): threadIds.append(threadable.getThreadID()) on_trans1_insert.wait() yield Transaction(name="TEST1").save() barrier2.wait() # wait here to delay commit
def trans(txn, i): yield Transaction(name=str(i)).save() if i % 2 == 1: txn.rollback() else: txn.commit()
def trans1(txn): yield Transaction(name="TEST1").save() with nested_transaction() as txn2: yield Transaction(name="TEST2").save() txn2.rollback() yield Transaction(name="TEST3").save()
def trans1(txn): threadIds.append(threadable.getThreadID()) yield Transaction(name="TEST1").save()
def trans(txn): yield Transaction(name="TEST1").save() yield Transaction(name="TEST2").save() barrier.wait() # wait here to delay commit raise ZeroDivisionError()
def trans2(txn): yield Transaction(name="TEST1").save() with nested_transaction(): yield Transaction(name="TEST2").save() yield trans1() yield Transaction(name="TEST5").save()