Reputation: 780
The datastore sometimes has methods that accepts a transaction as an argument. For example, there is datastore.get(key)
, and at the same time there is datastore.get(transaction, key)
. The Documentation here says that the latter version 'executes within the provided transaction'.
But if I use a transaction like this, it seems there is no need to pass in the transaction.
Transaction tx = datastore.beginTransaction();
Entity tom = datastore.get(key); //no need to pass in a transaction
tom.setProperty("age", 40);
datastore.put(tom);
tx.commit();
How and when am I supposed to use datastore.get(transaction, key)
?
Thanks in advance!
Upvotes: 1
Views: 328
Reputation: 596
Your example will work just fine as long as you use the referenced Datastore from only one thread, and have only one active transaction at a time in that thread.
You would use the "get(txn, key)" form with explicit transaction objects when you want to have multiple active transactions at a time. For example, the following code changes two entities in parallel without entangling them both in a cross-group transaction:
Transaction tx1 = datastore.beginTransaction();
Transaction tx2 = datastore.beginTransaction();
Entity tom = datastore.get(tx1, key1);
Entity bob = datastore.get(tx2, key2);
tom.setProperty("age", 40);
bob.setProperty("age", 45);
datastore.put(tx1, tom);
datastore.put(tx2, tom);
tx1.commit();
tx2.commit();
Upvotes: 1
Reputation: 780
OK it turns out that the answer lies in the same documentation which I read...
Here explains the difference between get(key)
and its overload get(transaction, key)
.
The DatastoreService provides synchronous access to a schema-less data storage system. The fundamental unit of data in this system is the Entity, which has an immutable identity (represented by a Key) and zero of more mutable properties. Entity objects can be created, updated, deleted, retrieved by identifier, and queried via a combination of properties. The DatastoreService can be used transactionally and supports the notion of a "current" transaction. A current transaction is established by calling beginTransaction(). The transaction returned by this method ceases to be current when an attempt is made to commit or rollback or when another call is made to beginTransaction(). A transaction can only be current within the Thread that created it.
The various overloads of put, get, and delete all support transactions. Users of this class have the choice of explicitly passing a (potentially null) Transaction to these methods or relying on the behavior governed by the ImplicitTransactionManagementPolicy. If a user explicitly provides a Transaction it is up to the user to call Transaction.commit() or Transaction.rollback() at the proper time. If a user relies on implicit transaction management and the installed policy creates a transaction, that transaction will be committed (in the case of a success) or rolled back (in the case of a failure) before the operation returns to the user. The methods that manage transactions according to ImplicitTransactionManagementPolicy are: delete(Key...), delete(Iterable), get(Key), get(Iterable), put(Entity), and put(Iterable).
The overload of prepare that takes a Transaction parameter behaves the same as the overloads of put, get, and delete that take a Transaction parameter. However, the overload of prepare that does not take a Transaction parameter, unlike put, get, and delete, does not use an existing Transaction if one is already running and does not consult the ImplicitTransactionManagementPolicy if one is not already running.
Upvotes: 1