KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > tx > ThreadTransactionContext


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.object.tx;
5
6 import com.tc.object.lockmanager.api.LockID;
7 import com.tc.util.Assert;
8 import com.tc.util.Stack;
9
10 import java.util.Iterator JavaDoc;
11
12 /**
13  * We have two concepts. Transactions which carry changes/creates etc... And the locks That are associated with those
14  * transactions. Transactions need to be created and then continued until the next transaction exit (in other words not
15  * just until the next begin) if we are to maintain proper semantics/ordering. The Locks on the otherhand work more like
16  * a stack. When a block is entered the locks get pushed onto the stack and associated with the current transaction and
17  * when they are exited they are removed from the current transaction. This class maintains both the current transaction
18  * and the stack of contexts that are associated with the thread.
19  */

20 public class ThreadTransactionContext {
21   private ClientTransaction currentTransaction;
22   private Stack transactionStack = new Stack();
23
24   public void setCurrentTransaction(ClientTransaction tx) {
25     Assert.eval(tx != null);
26     this.currentTransaction = tx;
27   }
28
29   public ClientTransaction getCurrentTransaction() {
30     return currentTransaction;
31   }
32
33   public ClientTransaction popCurrentTransaction() {
34     transactionStack.pop();
35     ClientTransaction ctx = currentTransaction;
36     currentTransaction = null;
37     return ctx;
38   }
39   
40   public TransactionContext peekContext(LockID id) {
41     if (transactionStack.isEmpty()) return null;
42     int len = transactionStack.size();
43     TransactionContext tc = null;
44     int i=len-1;
45     for (; i>=0; i--) {
46       tc = (TransactionContext) transactionStack.get(i);
47       if (tc.getLockID().equals(id)) {
48         return tc;
49       }
50     }
51     return null;
52   }
53   
54   public ClientTransaction popCurrentTransaction(LockID id) {
55     int len = transactionStack.size();
56     boolean found = false;
57     TransactionContext tc = null;
58     int i=len-1;
59     for (; i>=0; i--) {
60       tc = (TransactionContext) transactionStack.get(i);
61       if (tc.getLockID().equals(id)) {
62         found = true;
63         break;
64       }
65     }
66     if (found) {
67       for (int j=i+1; j<len; j++) {
68         tc = (TransactionContext)transactionStack.get(j);
69         tc.removeLock(id);
70       }
71       transactionStack.remove(i);
72     }
73     
74     ClientTransaction ctx = currentTransaction;
75     currentTransaction = null;
76     return ctx;
77   }
78
79   public void pushContext(LockID id, TxnType txType) {
80     transactionStack.push(new TransactionContext(id, txType, getAllLockIDs(id)));
81   }
82
83   private LockID[] getAllLockIDs(LockID id) {
84     LockID[] lids = new LockID[transactionStack.size() + 1];
85     lids[0] = id;
86     for (int i = 1; i < lids.length; i++) {
87       TransactionContext tc = (TransactionContext) transactionStack.get(i - 1);
88       lids[i] = tc.getLockID();
89     }
90     return lids;
91   }
92   
93   public void removeLock(LockID id) {
94     for (Iterator JavaDoc i=transactionStack.iterator(); i.hasNext(); ) {
95       TransactionContext tc = (TransactionContext) i.next();
96       if (id.equals(tc.getLockID())) {
97         i.remove();
98       } else {
99         tc.removeLock(id);
100       }
101     }
102   }
103
104   public TransactionContext peekContext() {
105     if (transactionStack.isEmpty()) return null;
106     return (TransactionContext) transactionStack.peek();
107   }
108 }
109
Popular Tags