View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.omid.transaction;
19  
20  import com.google.common.base.Optional;
21  import org.apache.omid.tso.client.CellId;
22  
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  /**
30   * Omid's base abstract implementation of the {@link Transaction} interface.
31   * Provides extra methods to access other basic transaction state required by
32   * {@link TransactionManagerExtension} implementations based on snapshot
33   * isolation.
34   *
35   * So, this abstract class must be extended by particular implementations of
36   * transaction managers related to different storage systems (HBase...)
37   */
38  public abstract class AbstractTransaction<T extends CellId> implements Transaction {
39  
40      private transient Map<String, Object> metadata = new HashMap<>();
41      private final AbstractTransactionManager transactionManager;
42      private final long startTimestamp;
43      private final long epoch;
44      private long commitTimestamp;
45      private boolean isRollbackOnly;
46      private final Set<T> writeSet;
47      private Status status = Status.RUNNING;
48  
49      /**
50       * Base constructor
51       *
52       * @param transactionId
53       *            transaction identifier to assign
54       * @param epoch
55       *            epoch of the TSOServer instance that created this transaction
56       *            Used in High Availability to guarantee data consistency
57       * @param writeSet
58       *            initial write set for the transaction.
59       *            Should be empty in most cases.
60       * @param transactionManager
61       *            transaction manager associated to this transaction.
62       *            Usually, should be the one that created the transaction
63       *            instance.
64       */
65      public AbstractTransaction(long transactionId,
66                                 long epoch,
67                                 Set<T> writeSet,
68                                 AbstractTransactionManager transactionManager) {
69          this.startTimestamp = transactionId;
70          this.epoch = epoch;
71          this.writeSet = writeSet;
72          this.transactionManager = transactionManager;
73      }
74  
75      /**
76       * Allows to define specific clean-up task for transaction implementations
77       */
78      public abstract void cleanup();
79  
80      /**
81       * @see org.apache.omid.transaction.Transaction#getTransactionId()
82       */
83      @Override
84      public long getTransactionId() {
85          return startTimestamp;
86      }
87  
88      /**
89       * @see org.apache.omid.transaction.Transaction#getEpoch()
90       */
91      @Override
92      public long getEpoch() {
93          return epoch;
94      }
95  
96      /**
97       * @see org.apache.omid.transaction.Transaction#getStatus()
98       */
99      @Override
100     public Status getStatus() {
101         return status;
102     }
103 
104     /**
105      * @see Transaction#isRollbackOnly()
106      */
107     @Override
108     public void setRollbackOnly() {
109         isRollbackOnly = true;
110     }
111 
112     /**
113      * @see org.apache.omid.transaction.Transaction#isRollbackOnly()
114      */
115     @Override
116     public boolean isRollbackOnly() {
117         return isRollbackOnly;
118     }
119 
120     /**
121      * Returns transaction manager associated to this transaction.
122      * @return transaction manager
123      */
124     public AbstractTransactionManager getTransactionManager() {
125         return transactionManager;
126     }
127 
128     /**
129      * Returns the start timestamp for this transaction.
130      * @return start timestamp
131      */
132     public long getStartTimestamp() {
133         return startTimestamp;
134     }
135 
136     /**
137      * Returns the commit timestamp for this transaction.
138      * @return commit timestamp
139      */
140     public long getCommitTimestamp() {
141         return commitTimestamp;
142     }
143 
144     /**
145      * Sets the commit timestamp for this transaction.
146      * @param commitTimestamp
147      *            the commit timestamp to set
148      */
149     public void setCommitTimestamp(long commitTimestamp) {
150         this.commitTimestamp = commitTimestamp;
151     }
152 
153     /**
154      * Sets the status for this transaction.
155      * @param status
156      *            the {@link Status} to set
157      */
158     public void setStatus(Status status) {
159         this.status = status;
160     }
161 
162     /**
163      * Returns the current write-set for this transaction.
164      * @return write set
165      */
166     public Set<T> getWriteSet() {
167         return writeSet;
168     }
169 
170     /**
171      * Adds an element to the transaction write-set.
172      * @param element
173      *            the element to add
174      */
175     public void addWriteSetElement(T element) {
176         writeSet.add(element);
177     }
178 
179     @Override
180     public String toString() {
181         return String.format("Tx-%s [%s] (ST=%d, CT=%d, Epoch=%d) WriteSet %s",
182                              Long.toHexString(getTransactionId()),
183                              status,
184                              startTimestamp,
185                              commitTimestamp,
186                              epoch,
187                              writeSet);
188     }
189 
190     @Override
191     public Optional<Object> getMetadata(String key) {
192         return Optional.fromNullable(metadata.get(key));
193     }
194 
195     /**
196      * Expects they metadata stored under key "key" to be of the "Set" type,
197      * append "value" to the existing set or creates a new one
198      */
199     @Override
200     @SuppressWarnings("unchecked")
201     public void appendMetadata(String key, Object value) {
202         List existingValue = (List) metadata.get(key);
203         if (existingValue == null) {
204             List<Object> newList = new ArrayList<>();
205             newList.add(value);
206             metadata.put(key, newList);
207         } else {
208             existingValue.add(value);
209         }
210     }
211 
212     @Override
213     public void setMetadata(String key, Object value) {
214         metadata.put(key, value);
215     }
216 
217 }