From e5ec0a179eaeb6d72dd09144dda9e861b2a4999f Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 24 Sep 2014 18:35:45 -0400 Subject: [PATCH 1/3] Fix #136: roll back transactions on exceptions. Cherry-pick: 3221122ad1eff0e96636b440d996226c737890e8 --- gcloud/datastore/test_transaction.py | 12 ++++-------- gcloud/datastore/transaction.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/gcloud/datastore/test_transaction.py b/gcloud/datastore/test_transaction.py index b0841489a158..3a7080a3f1db 100644 --- a/gcloud/datastore/test_transaction.py +++ b/gcloud/datastore/test_transaction.py @@ -112,7 +112,6 @@ def test_context_manager_no_raise(self): self.assertEqual(xact.id(), None) def test_context_manager_w_raise(self): - # See https://github.com/GoogleCloudPlatform/gcloud-python/issues/136 class Foo(Exception): pass _DATASET = 'DATASET' @@ -127,13 +126,10 @@ class Foo(Exception): self.assertTrue(connection._xact is xact) raise Foo() except Foo: - pass # XXX - # self.assertEqual(xact.id(), None) - # self.assertEqual(connection._rolled_back, _DATASET)) - # self.assertEqual(connection._xact, None) - # XXX should *not* have committed - self.assertEqual(connection._committed, (_DATASET, mutation)) - # self.assertEqual(connection._committed, None) + self.assertEqual(xact.id(), None) + self.assertEqual(connection._rolled_back, _DATASET) + self.assertEqual(connection._xact, None) + self.assertEqual(connection._committed, None) self.assertTrue(connection._xact is None) self.assertEqual(xact.id(), None) diff --git a/gcloud/datastore/transaction.py b/gcloud/datastore/transaction.py index c8cf88979e05..511c14672e96 100644 --- a/gcloud/datastore/transaction.py +++ b/gcloud/datastore/transaction.py @@ -21,18 +21,15 @@ class Transaction(object): ... entity1.save() ... entity2.save() - To rollback a transaction if there is an error:: + By derault, the transaction is rolled back is an error:: >>> from gcloud import datastore >>> dataset = datastore.get_dataset('dataset-id', email, key_path) >>> with dataset.transaction() as t: - ... try: - ... do_some_work() - ... entity1.save() - ... except: - ... t.rollback() + ... do_some_work() + ... raise Exception() # rolls back - If the transaction isn't rolled back, + If the transaction block exists without an exception, it will commit by default. .. warning:: @@ -249,4 +246,7 @@ def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): - self.commit() + if exc_type is None: + self.commit() + else: + self.rollback() From fb0d8dc9a3eab9c3777ddea2256cd954a6e9d0ef Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 30 Sep 2014 14:30:59 -0400 Subject: [PATCH 2/3] Fix typo, s/derault/default. Feedback from @silvolu. --- gcloud/datastore/transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud/datastore/transaction.py b/gcloud/datastore/transaction.py index 511c14672e96..50e1cf957589 100644 --- a/gcloud/datastore/transaction.py +++ b/gcloud/datastore/transaction.py @@ -21,7 +21,7 @@ class Transaction(object): ... entity1.save() ... entity2.save() - By derault, the transaction is rolled back is an error:: + By default, the transaction is rolled back is an error:: >>> from gcloud import datastore >>> dataset = datastore.get_dataset('dataset-id', email, key_path) From 8e09bfd11fddd4ac4991f8bf2e039b206ed42de8 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 1 Oct 2014 16:51:22 -0400 Subject: [PATCH 3/3] Clarify sentence. Feedback from @silvolu. --- gcloud/datastore/transaction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcloud/datastore/transaction.py b/gcloud/datastore/transaction.py index 50e1cf957589..c218c544ee0e 100644 --- a/gcloud/datastore/transaction.py +++ b/gcloud/datastore/transaction.py @@ -21,7 +21,8 @@ class Transaction(object): ... entity1.save() ... entity2.save() - By default, the transaction is rolled back is an error:: + By default, the transaction is rolled back if the transaction block + exits with an error:: >>> from gcloud import datastore >>> dataset = datastore.get_dataset('dataset-id', email, key_path)