KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > OpenTransactionList


1 /**
2  * com.mckoi.database.OpenTransactionList 26 Nov 2000
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database;
26
27 import java.util.ArrayList JavaDoc;
28 import com.mckoi.debug.Lvl;
29
30 /**
31  * The list of all currently open transactions. This is a thread safe
32  * object that is shared between a TableDataConglomerate and its children
33  * MasterDataTableSource objects. It is used for maintaining a list of
34  * transactions that are currently open in the system. It also provides
35  * various utility methods around the list.
36  * <p>
37  * This class is thread safe and can safely be accessed by multiple threads.
38  * This is so threads accessing table source information as well as
39  * conglomerate 'commit' stages can safely access this object.
40  *
41  * @author Tobias Downer
42  */

43
44 final class OpenTransactionList {
45
46   /**
47    * True to enable transaction tracking.
48    */

49   private static final boolean TRACKING = false;
50   
51   /**
52    * The system that this transaction list is part of.
53    */

54   private TransactionSystem system;
55
56   /**
57    * The list of open transactions.
58    * (Transaction).
59    */

60   private ArrayList JavaDoc open_transactions;
61
62   /**
63    * A list of Error objects created when the transaction is added to the open
64    * transactions list.
65    */

66   private ArrayList JavaDoc open_transaction_stacks;
67   
68   /**
69    * The minimum commit id of the current list.
70    */

71   private long minimum_commit_id;
72
73   /**
74    * The maximum commit id of the current list.
75    */

76   private long maximum_commit_id;
77
78   /**
79    * Creates the list.
80    */

81   OpenTransactionList(TransactionSystem system) {
82     this.system = system;
83     open_transactions = new ArrayList JavaDoc();
84     if (TRACKING) {
85       open_transaction_stacks = new ArrayList JavaDoc();
86     }
87     minimum_commit_id = Long.MAX_VALUE;
88     maximum_commit_id = 0;
89   }
90
91   /**
92    * Adds a new open transaction to the list. Transactions must be added
93    * in order of commit_id.
94    */

95   synchronized void addTransaction(Transaction transaction) {
96     long current_commit_id = transaction.getCommitID();
97     if (current_commit_id >= maximum_commit_id) {
98       open_transactions.add(transaction);
99       if (TRACKING) {
100         open_transaction_stacks.add(new Error JavaDoc());
101       }
102       system.stats().increment("OpenTransactionList.count");
103       maximum_commit_id = current_commit_id;
104     }
105     else {
106       throw new Error JavaDoc(
107                    "Added a transaction with a lower than maximum commit_id");
108     }
109   }
110
111   /**
112    * Removes an open transaction from the list.
113    */

114   synchronized void removeTransaction(Transaction transaction) {
115     
116     int size = open_transactions.size();
117     int i = open_transactions.indexOf(transaction);
118     if (i == 0) {
119       // First in list.
120
if (i == size - 1) {
121         // And last.
122
minimum_commit_id = Integer.MAX_VALUE;
123         maximum_commit_id = 0;
124       }
125       else {
126         minimum_commit_id =
127                    ((Transaction) open_transactions.get(i + 1)).getCommitID();
128       }
129     }
130     else if (i == open_transactions.size() - 1) {
131       // Last in list.
132
maximum_commit_id =
133                    ((Transaction) open_transactions.get(i - 1)).getCommitID();
134     }
135     else if (i == -1) {
136       throw new Error JavaDoc("Unable to find transaction in the list.");
137     }
138     open_transactions.remove(i);
139     if (TRACKING) {
140       open_transaction_stacks.remove(i);
141     }
142     system.stats().decrement("OpenTransactionList.count");
143
144     if (TRACKING) {
145       system.Debug().write(Lvl.MESSAGE, this, "Stacks:");
146       for (int n = 0; n < open_transaction_stacks.size(); ++n) {
147         system.Debug().writeException(Lvl.MESSAGE,
148                                       (Error JavaDoc) open_transaction_stacks.get(n));
149       }
150     }
151
152   }
153
154   /**
155    * Returns the number of transactions that are open on the conglomerate.
156    */

157   synchronized int count() {
158     return open_transactions.size();
159   }
160
161   /**
162    * Returns the minimum commit id not including the given transaction object.
163    * Returns Long.MAX_VALUE if there are no open transactions in the list
164    * (not including the given transaction).
165    */

166   synchronized long minimumCommitID(Transaction transaction) {
167
168     long minimum_commit_id = Long.MAX_VALUE;
169     if (open_transactions.size() > 0) {
170       // If the bottom transaction is this transaction, then go to the
171
// next up from the bottom (we don't count this transaction as the
172
// minimum commit_id).
173
Transaction test_transaction = (Transaction)open_transactions.get(0);
174       if (test_transaction != transaction) {
175         minimum_commit_id = test_transaction.getCommitID();
176       }
177       else if (open_transactions.size() > 1) {
178         minimum_commit_id =
179                         ((Transaction) open_transactions.get(1)).getCommitID();
180       }
181     }
182
183     return minimum_commit_id;
184
185   }
186
187   public synchronized String JavaDoc toString() {
188     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
189     buf.append("[ OpenTransactionList: ");
190     for (int i = 0; i < open_transactions.size(); ++i) {
191       Transaction t = (Transaction) open_transactions.get(i);
192       buf.append(t.getCommitID());
193       buf.append(", ");
194     }
195     buf.append(" ]");
196     return new String JavaDoc(buf);
197   }
198
199 }
200
Popular Tags