1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com
.google
.appengine
.api
.datastore
;
4 import com
.google
.appengine
.api
.utils
.FutureWrapper
;
5 import com
.google
.apphosting
.api
.ApiBasePb
;
6 import com
.google
.apphosting
.api
.ApiProxy
;
7 import com
.google
.apphosting
.api
.ApiProxy
.ApiConfig
;
8 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
;
9 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
.CommitResponse
;
10 import com
.google
.apphosting
.datastore
.DatastoreV3Pb
.DatastoreService_3
.Method
;
11 import com
.google
.io
.protocol
.ProtocolMessage
;
13 import java
.util
.concurrent
.Future
;
16 * Implementation of the V3-specific logic to handle a {@link Transaction}.
18 * All calls are routed through the {@link ApiProxy}.
20 class InternalTransactionV3
implements TransactionImpl
.InternalTransaction
{
22 private final ApiConfig apiConfig
;
23 private final String app
;
25 * The {@link Future} associated with the BeginTransaction RPC we sent to the
28 private final Future
<DatastoreV3Pb
.Transaction
> beginTxnFuture
;
30 InternalTransactionV3(ApiConfig apiConfig
, String app
,
31 Future
<DatastoreV3Pb
.Transaction
> beginTxnFuture
) {
32 this.apiConfig
= apiConfig
;
34 this.beginTxnFuture
= beginTxnFuture
;
38 * Provides the unique identifier for the txn.
39 * Blocks on the future since the handle comes back from the datastore
42 private long getHandle() {
43 return FutureHelper
.quietGet(beginTxnFuture
).getHandle();
46 <T
extends ProtocolMessage
<T
>> Future
<Void
> makeAsyncCall(
47 Method method
, ProtocolMessage
<?
> request
, T response
) {
48 Future
<T
> resultProto
= DatastoreApiHelper
.makeAsyncCall(apiConfig
, method
, request
, response
);
49 return new FutureWrapper
<T
, Void
>(resultProto
) {
51 protected Void
wrap(T ignore
) throws Exception
{
56 protected Throwable
convertException(Throwable cause
) {
62 private <T
extends ProtocolMessage
<T
>> Future
<Void
> makeAsyncTxnCall(Method method
, T response
) {
63 DatastoreV3Pb
.Transaction txn
= new DatastoreV3Pb
.Transaction();
65 txn
.setHandle(getHandle());
66 return makeAsyncCall(method
, txn
, response
);
70 public Future
<Void
> doCommitAsync() {
71 return makeAsyncTxnCall(Method
.Commit
, new CommitResponse());
75 public Future
<Void
> doRollbackAsync() {
76 return makeAsyncTxnCall(Method
.Rollback
, new ApiBasePb
.VoidProto());
80 public String
getId() {
81 return Long
.toString(getHandle());
85 public boolean equals(Object o
) {
89 if (o
== null || getClass() != o
.getClass()) {
93 InternalTransactionV3 that
= (InternalTransactionV3
) o
;
95 return getHandle() == that
.getHandle();
99 public int hashCode() {
100 return (int) (getHandle() ^
(getHandle() >>> 32));
103 static DatastoreV3Pb
.Transaction
toProto(Transaction txn
) {
104 DatastoreV3Pb
.Transaction txnProto
= new DatastoreV3Pb
.Transaction();
105 txnProto
.setApp(txn
.getApp());
106 txnProto
.setHandle(Long
.parseLong(txn
.getId()));