Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 248b688

Browse filesBrowse files
committed
Add 'serializable' flag to Transaction.
Closes googleapis#1204.
1 parent 2ef1639 commit 248b688
Copy full SHA for 248b688

5 files changed

+87-20Lines changed: 87 additions & 20 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎gcloud/datastore/client.py‎

Copy file name to clipboardExpand all lines: gcloud/datastore/client.py
+7-2Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,12 +440,17 @@ def batch(self):
440440
"""
441441
return Batch(self)
442442

443-
def transaction(self):
443+
def transaction(self, serializable=False):
444444
"""Proxy to :class:`gcloud.datastore.transaction.Transaction`.
445445
446446
Passes our ``dataset_id``.
447+
448+
:type serializable: boolean
449+
:param serializable: if true, perform this transaction at
450+
``serializable`` isolation level; otherwise,
451+
perform it at ``snapshot`` level.
447452
"""
448-
return Transaction(self)
453+
return Transaction(self, serializable=serializable)
449454

450455
def query(self, **kwargs):
451456
"""Proxy to :class:`gcloud.datastore.query.Query`.
Collapse file

‎gcloud/datastore/test_client.py‎

Copy file name to clipboardExpand all lines: gcloud/datastore/test_client.py
+16-2Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ def test_batch(self):
790790
self.assertEqual(batch.args, (client,))
791791
self.assertEqual(batch.kwargs, {})
792792

793-
def test_transaction(self):
793+
def test_transaction_defaults(self):
794794
from gcloud.datastore import client as MUT
795795
from gcloud._testing import _Monkey
796796

@@ -802,7 +802,21 @@ def test_transaction(self):
802802

803803
self.assertTrue(isinstance(xact, _Dummy))
804804
self.assertEqual(xact.args, (client,))
805-
self.assertEqual(xact.kwargs, {})
805+
self.assertEqual(xact.kwargs, {'serializable': False})
806+
807+
def test_transaction_explicit(self):
808+
from gcloud.datastore import client as MUT
809+
from gcloud._testing import _Monkey
810+
811+
creds = object()
812+
client = self._makeOne(credentials=creds)
813+
814+
with _Monkey(MUT, Transaction=_Dummy):
815+
xact = client.transaction(serializable=True)
816+
817+
self.assertTrue(isinstance(xact, _Dummy))
818+
self.assertEqual(xact.args, (client,))
819+
self.assertEqual(xact.kwargs, {'serializable': True})
806820

807821
def test_query_w_client(self):
808822
KIND = 'KIND'
Collapse file

‎gcloud/datastore/test_transaction.py‎

Copy file name to clipboardExpand all lines: gcloud/datastore/test_transaction.py
+41-11Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ def _getTargetClass(self):
2121
from gcloud.datastore.transaction import Transaction
2222
return Transaction
2323

24-
def _makeOne(self, client):
25-
return self._getTargetClass()(client)
24+
def _makeOne(self, client, **kw):
25+
return self._getTargetClass()(client, **kw)
2626

27-
def test_ctor(self):
27+
def test_ctor_defaults(self):
2828
from gcloud.datastore._datastore_v1_pb2 import Mutation
2929

3030
_DATASET = 'DATASET'
@@ -37,6 +37,22 @@ def test_ctor(self):
3737
self.assertEqual(xact._status, self._getTargetClass()._INITIAL)
3838
self.assertTrue(isinstance(xact.mutation, Mutation))
3939
self.assertEqual(len(xact._auto_id_entities), 0)
40+
self.assertFalse(xact.serializable)
41+
42+
def test_ctor_explicit(self):
43+
from gcloud.datastore._datastore_v1_pb2 import Mutation
44+
45+
_DATASET = 'DATASET'
46+
connection = _Connection()
47+
client = _Client(_DATASET, connection)
48+
xact = self._makeOne(client, serializable=True)
49+
self.assertEqual(xact.dataset_id, _DATASET)
50+
self.assertEqual(xact.connection, connection)
51+
self.assertEqual(xact.id, None)
52+
self.assertEqual(xact._status, self._getTargetClass()._INITIAL)
53+
self.assertTrue(isinstance(xact.mutation, Mutation))
54+
self.assertEqual(len(xact._auto_id_entities), 0)
55+
self.assertTrue(xact.serializable)
4056

4157
def test_current(self):
4258
from gcloud.datastore.test_client import _NoCommitBatch
@@ -64,14 +80,25 @@ def test_current(self):
6480
self.assertTrue(xact1.current() is None)
6581
self.assertTrue(xact2.current() is None)
6682

67-
def test_begin(self):
83+
def test_begin_wo_serializable(self):
6884
_DATASET = 'DATASET'
6985
connection = _Connection(234)
7086
client = _Client(_DATASET, connection)
7187
xact = self._makeOne(client)
7288
xact.begin()
7389
self.assertEqual(xact.id, 234)
74-
self.assertEqual(connection._begun, _DATASET)
90+
self.assertEqual(connection._begun[0], _DATASET)
91+
self.assertFalse(connection._begun[1])
92+
93+
def test_begin_w_serializable(self):
94+
_DATASET = 'DATASET'
95+
connection = _Connection(234)
96+
client = _Client(_DATASET, connection)
97+
xact = self._makeOne(client, serializable=True)
98+
xact.begin()
99+
self.assertEqual(xact.id, 234)
100+
self.assertEqual(connection._begun[0], _DATASET)
101+
self.assertTrue(connection._begun[1])
75102

76103
def test_begin_tombstoned(self):
77104
_DATASET = 'DATASET'
@@ -80,7 +107,8 @@ def test_begin_tombstoned(self):
80107
xact = self._makeOne(client)
81108
xact.begin()
82109
self.assertEqual(xact.id, 234)
83-
self.assertEqual(connection._begun, _DATASET)
110+
self.assertEqual(connection._begun[0], _DATASET)
111+
self.assertFalse(connection._begun[1])
84112

85113
xact.rollback()
86114
self.assertEqual(xact.id, None)
@@ -134,7 +162,8 @@ def test_context_manager_no_raise(self):
134162
xact._mutation = mutation = object()
135163
with xact:
136164
self.assertEqual(xact.id, 234)
137-
self.assertEqual(connection._begun, _DATASET)
165+
self.assertEqual(connection._begun[0], _DATASET)
166+
self.assertFalse(connection._begun[1])
138167
self.assertEqual(connection._committed, (_DATASET, mutation, 234))
139168
self.assertEqual(xact.id, None)
140169

@@ -146,12 +175,13 @@ class Foo(Exception):
146175
_DATASET = 'DATASET'
147176
connection = _Connection(234)
148177
client = _Client(_DATASET, connection)
149-
xact = self._makeOne(client)
178+
xact = self._makeOne(client, serializable=True)
150179
xact._mutation = object()
151180
try:
152181
with xact:
153182
self.assertEqual(xact.id, 234)
154-
self.assertEqual(connection._begun, _DATASET)
183+
self.assertEqual(connection._begun[0], _DATASET)
184+
self.assertTrue(connection._begun[1])
155185
raise Foo()
156186
except Foo:
157187
self.assertEqual(xact.id, None)
@@ -179,8 +209,8 @@ def __init__(self, xact_id=123):
179209
self._xact_id = xact_id
180210
self._commit_result = _CommitResult()
181211

182-
def begin_transaction(self, dataset_id):
183-
self._begun = dataset_id
212+
def begin_transaction(self, dataset_id, serializable):
213+
self._begun = (dataset_id, serializable)
184214
return self._xact_id
185215

186216
def rollback(self, dataset_id, transaction_id):
Collapse file

‎gcloud/datastore/transaction.py‎

Copy file name to clipboardExpand all lines: gcloud/datastore/transaction.py
+21-3Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,12 @@ class Transaction(Batch):
8585
... transaction.commit()
8686
8787
:type client: :class:`gcloud.datastore.client.Client`
88-
:param client: The client used to connect to datastore.
88+
:param client: the client used to connect to datastore.
89+
90+
:type serializable: boolean
91+
:param serializable: if true, perform this transaction at
92+
``serializable`` isolation level; otherwise, perform
93+
it at ``snapshot`` level.
8994
"""
9095

9196
_INITIAL = 0
@@ -100,10 +105,11 @@ class Transaction(Batch):
100105
_FINISHED = 3
101106
"""Enum value for _FINISHED status of transaction."""
102107

103-
def __init__(self, client):
108+
def __init__(self, client, serializable=False):
104109
super(Transaction, self).__init__(client)
105110
self._id = None
106111
self._status = self._INITIAL
112+
self._serializable = serializable
107113

108114
@property
109115
def id(self):
@@ -114,6 +120,17 @@ def id(self):
114120
"""
115121
return self._id
116122

123+
@property
124+
def serializable(self):
125+
"""Should this transaction be run at ``serializable`` isolation
126+
127+
:rtype: boolean
128+
:returns: if true, perform this transaction at
129+
``serializable`` isolation level; otherwise, perform
130+
it at ``snapshot`` level.
131+
"""
132+
return self._serializable
133+
117134
def current(self):
118135
"""Return the topmost transaction.
119136
@@ -138,7 +155,8 @@ def begin(self):
138155
if self._status != self._INITIAL:
139156
raise ValueError('Transaction already started previously.')
140157
self._status = self._IN_PROGRESS
141-
self._id = self.connection.begin_transaction(self.dataset_id)
158+
self._id = self.connection.begin_transaction(
159+
self.dataset_id, serializable=self.serializable)
142160

143161
def rollback(self):
144162
"""Rolls back the current transaction.
Collapse file

‎system_tests/datastore.py‎

Copy file name to clipboardExpand all lines: system_tests/datastore.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ def test_post_with_id(self):
107107
def test_post_with_generated_id(self):
108108
self._generic_test_post()
109109

110-
def test_save_multiple(self):
111-
with CLIENT.transaction() as xact:
110+
def test_save_multiple_serializable(self):
111+
with CLIENT.transaction(serializable=True) as xact:
112112
entity1 = self._get_post()
113113
xact.put(entity1)
114114
# Register entity to be deleted.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.