001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2002-2004 French National Institute For Research In Computer
004: * Science And Control (INRIA).
005: * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
006: * Contact: sequoia@continuent.org
007: *
008: * Licensed under the Apache License, Version 2.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: * Initial developer(s): Emmanuel Cecchet.
021: * Contributor(s): Peter Royal.
022: */package org.continuent.sequoia.controller.requestmanager;
023:
024: import java.io.Serializable;
025: import java.util.HashMap;
026: import java.util.LinkedList;
027: import java.util.List;
028: import java.util.Map;
029:
030: import org.continuent.sequoia.common.locks.TransactionLogicalLock;
031: import org.continuent.sequoia.controller.backend.DatabaseBackend;
032:
033: /**
034: * This class carry transaction metadata including the transaction state.
035: * <p>
036: * Metadata include a transaction id, a login and a timeout. The state is used
037: * to track if a transaction is read-only or read-write and what kind of write
038: * accesses have been made in the transaction in case invalidations are needed
039: * at commit or rollback time.
040: * <p>
041: * The type is made serializable only for unlog messages that have to be sent
042: * between controllers.
043: *
044: * @author <a href="mailto:emmanuel.cecchet@emicnetworks.com">Emmanuel Cecchet</a>
045: * @version 2.2
046: */
047: public class TransactionMetaData implements Serializable {
048: private static final long serialVersionUID = -5251053474824677394L;
049:
050: private final long transactionId;
051: private long timeout;
052: private long timestamp;
053: private String login;
054: private final boolean isPersistentConnection;
055: private final long persistentConnectionId;
056: /** Recovery log id of the last commit/rollback operation on this transaction */
057: private transient long logId;
058: /** Map of Lists of locksMap taken by this task, indexed by backend */
059: private transient Map locksMap = new HashMap();
060: private transient boolean altersAggregateList = false;
061: private transient boolean altersDatabaseCatalog = false;
062: private transient boolean altersDatabaseSchema = false;
063: private transient boolean altersMetadataCache = false;
064: private transient boolean altersQueryResultCache = false;
065: private transient boolean altersSomething = false;
066: private transient boolean altersStoredProcedureList = false;
067: private transient boolean altersUserDefinedTypes = false;
068: private transient boolean altersUsers = false;
069: private transient boolean isReadOnly = true;
070:
071: /**
072: * Creates a new <code>TransactionMetaData</code>.
073: *
074: * @param transactionId the transaction identifier.
075: * @param timeout the transaction timeout in seconds.
076: * @param login the user login.
077: * @param isPersistentConnection true if the transaction is started on a
078: * persistent connection
079: * @param persistentConnectionId persistent connection id if the transaction
080: * must be started on a persistent connection
081: */
082: public TransactionMetaData(long transactionId, long timeout,
083: String login, boolean isPersistentConnection,
084: long persistentConnectionId) {
085: this .transactionId = transactionId;
086: this .timeout = timeout;
087: this .login = login;
088: this .isPersistentConnection = isPersistentConnection;
089: this .persistentConnectionId = persistentConnectionId;
090: this .timestamp = System.currentTimeMillis();
091: }
092:
093: /**
094: * Add a lock to the list of locks acquired by the given backend on this
095: * transaction
096: *
097: * @param backend backend acquiring the lock
098: * @param lock the lock that has been acquired
099: */
100: public synchronized void addAcquiredLock(DatabaseBackend backend,
101: TransactionLogicalLock lock) {
102: LinkedList acquiredLocks = (LinkedList) locksMap.get(backend);
103: if (acquiredLocks == null) {
104: acquiredLocks = new LinkedList();
105: locksMap.put(backend, acquiredLocks);
106: }
107: acquiredLocks.add(lock);
108: }
109:
110: /**
111: * Add locks to the list of locks acquired by the given backend on this
112: * transaction
113: *
114: * @param backend backend acquiring the locks
115: * @param locks the locks that have been acquired
116: */
117: public synchronized void addAcquiredLocks(DatabaseBackend backend,
118: List locks) {
119: LinkedList acquiredLocks = (LinkedList) locksMap.get(backend);
120: if (acquiredLocks == null) {
121: acquiredLocks = new LinkedList();
122: locksMap.put(backend, acquiredLocks);
123: }
124: acquiredLocks.addAll(locks);
125: }
126:
127: /**
128: * Returns the altersAggregateList value.
129: *
130: * @return Returns the altersAggregateList.
131: */
132: public final boolean altersAggregateList() {
133: return altersAggregateList;
134: }
135:
136: /**
137: * Returns the altersDatabaseCatalog value.
138: *
139: * @return Returns the altersDatabaseCatalog.
140: */
141: public final boolean altersDatabaseCatalog() {
142: return altersDatabaseCatalog;
143: }
144:
145: /**
146: * Returns the altersDatabaseSchema value.
147: *
148: * @return Returns the altersDatabaseSchema.
149: */
150: public final boolean altersDatabaseSchema() {
151: return altersDatabaseSchema;
152: }
153:
154: /**
155: * Returns the altersMetadataCache value.
156: *
157: * @return Returns the altersMetadataCache.
158: */
159: public final boolean altersMetadataCache() {
160: return altersMetadataCache;
161: }
162:
163: /**
164: * Returns the altersQueryResultCache value.
165: *
166: * @return Returns the altersQueryResultCache.
167: */
168: public final boolean altersQueryResultCache() {
169: return altersQueryResultCache;
170: }
171:
172: /**
173: * Returns the altersSomething value.
174: *
175: * @return Returns the altersSomething.
176: */
177: public final boolean altersSomething() {
178: return altersSomething;
179: }
180:
181: /**
182: * Returns the altersStoredProcedureList value.
183: *
184: * @return Returns the altersStoredProcedureList.
185: */
186: public final boolean altersStoredProcedureList() {
187: return altersStoredProcedureList;
188: }
189:
190: /**
191: * Returns the altersUserDefinedTypes value.
192: *
193: * @return Returns the altersUserDefinedTypes.
194: */
195: public final boolean altersUserDefinedTypes() {
196: return altersUserDefinedTypes;
197: }
198:
199: /**
200: * Returns the altersUsers value.
201: *
202: * @return Returns the altersUsers.
203: */
204: public final boolean altersUsers() {
205: return altersUsers;
206: }
207:
208: /**
209: * Return the list of locks acquired by the given backend for this transaction
210: * or null if no lock has been acquired so far.
211: *
212: * @param backend backend for which we want to retrieve to set of locks
213: * @return the list of acquired locks for the given backend
214: */
215: public List getAcquiredLocks(DatabaseBackend backend) {
216: return (List) locksMap.get(backend);
217: }
218:
219: /**
220: * Returns the logId value.
221: *
222: * @return Returns the logId.
223: */
224: public final long getLogId() {
225: return logId;
226: }
227:
228: /**
229: * Sets the logId value.
230: *
231: * @param logId The logId to set.
232: */
233: public final void setLogId(long logId) {
234: this .logId = logId;
235: }
236:
237: /**
238: * Gets creation's timestamp of this TransactionMetaData.
239: *
240: * @return the timestamp corresponding to the creation of this TransactionMetaData.
241: */
242: public long getTimestamp() {
243: return timestamp;
244: }
245:
246: /**
247: * Returns the login.
248: *
249: * @return String
250: */
251: public String getLogin() {
252: return login;
253: }
254:
255: /**
256: * Returns the persistent connection id (only meaningful is
257: * isPersistentConnection is true).
258: *
259: * @return Returns the persistent connection id.
260: * @see #isPersistentConnection()
261: */
262: public final long getPersistentConnectionId() {
263: return persistentConnectionId;
264: }
265:
266: /**
267: * Returns the timeout.
268: *
269: * @return long
270: */
271: public long getTimeout() {
272: return timeout;
273: }
274:
275: /**
276: * Returns the transactionId.
277: *
278: * @return int
279: */
280: public long getTransactionId() {
281: return transactionId;
282: }
283:
284: /**
285: * Returns true if at least one backend is holding locks for this
286: * transactions.
287: *
288: * @return true if a backend has locks for the transactions
289: */
290: public boolean isLockedByBackends() {
291: return !locksMap.isEmpty();
292: }
293:
294: /**
295: * Returns true if the transaction executes on a persistent connection
296: * (retrieve the value using getPersistentConnectionId).
297: *
298: * @return Returns true if transaction uses a persistent connection.
299: * @see #getPersistentConnectionId()
300: */
301: public final boolean isPersistentConnection() {
302: return isPersistentConnection;
303: }
304:
305: /**
306: * Returns true if the transaction is read-only (true by default).
307: *
308: * @return Returns the isReadOnly.
309: */
310: public final boolean isReadOnly() {
311: return isReadOnly;
312: }
313:
314: /**
315: * Remove and return the lock list belonging to a backend.
316: *
317: * @param backend backend which locks should be removed
318: * @return the lock list or null if no lock were found for this backend
319: */
320: public List removeBackendLocks(DatabaseBackend backend) {
321: return (List) locksMap.remove(backend);
322: }
323:
324: /**
325: * Sets the altersAggregateList value.
326: *
327: * @param altersAggregateList The altersAggregateList to set.
328: */
329: public final void setAltersAggregateList(boolean altersAggregateList) {
330: this .altersAggregateList = altersAggregateList;
331: }
332:
333: /**
334: * Sets the altersDatabaseCatalog value.
335: *
336: * @param altersDatabaseCatalog The altersDatabaseCatalog to set.
337: */
338: public final void setAltersDatabaseCatalog(
339: boolean altersDatabaseCatalog) {
340: this .altersDatabaseCatalog = altersDatabaseCatalog;
341: }
342:
343: /**
344: * Sets the altersDatabaseSchema value.
345: *
346: * @param altersDatabaseSchema The altersDatabaseSchema to set.
347: */
348: public final void setAltersDatabaseSchema(
349: boolean altersDatabaseSchema) {
350: this .altersDatabaseSchema = altersDatabaseSchema;
351: }
352:
353: /**
354: * Sets the altersMetadataCache value.
355: *
356: * @param altersMetadataCache The altersMetadataCache to set.
357: */
358: public final void setAltersMetadataCache(boolean altersMetadataCache) {
359: this .altersMetadataCache = altersMetadataCache;
360: }
361:
362: /**
363: * Sets the altersQueryResultCache value.
364: *
365: * @param altersQueryResultCache The altersQueryResultCache to set.
366: */
367: public final void setAltersQueryResultCache(
368: boolean altersQueryResultCache) {
369: this .altersQueryResultCache = altersQueryResultCache;
370: }
371:
372: /**
373: * Sets the altersSomething value.
374: *
375: * @param altersSomething The altersSomething to set.
376: */
377: public final void setAltersSomething(boolean altersSomething) {
378: this .altersSomething = altersSomething;
379: }
380:
381: /**
382: * Sets the altersStoredProcedureList value.
383: *
384: * @param altersStoredProcedureList The altersStoredProcedureList to set.
385: */
386: public final void setAltersStoredProcedureList(
387: boolean altersStoredProcedureList) {
388: this .altersStoredProcedureList = altersStoredProcedureList;
389: }
390:
391: /**
392: * Sets the altersUserDefinedTypes value.
393: *
394: * @param altersUserDefinedTypes The altersUserDefinedTypes to set.
395: */
396: public final void setAltersUserDefinedTypes(
397: boolean altersUserDefinedTypes) {
398: this .altersUserDefinedTypes = altersUserDefinedTypes;
399: }
400:
401: /**
402: * Sets the altersUsers value.
403: *
404: * @param altersUsers The altersUsers to set.
405: */
406: public final void setAltersUsers(boolean altersUsers) {
407: this .altersUsers = altersUsers;
408: }
409:
410: /**
411: * Sets the isReadOnly value.
412: *
413: * @param isReadOnly The isReadOnly to set.
414: */
415: public final void setReadOnly(boolean isReadOnly) {
416: this .isReadOnly = isReadOnly;
417: }
418:
419: /**
420: * Sets the login.
421: *
422: * @param login the login to set.
423: */
424: public void setLogin(String login) {
425: this .login = login;
426: }
427:
428: /**
429: * Sets the timeout.
430: *
431: * @param timeout the timeout to set.
432: */
433: public void setTimeout(long timeout) {
434: this .timeout = timeout;
435: }
436:
437: /**
438: * @see java.lang.Object#equals(java.lang.Object)
439: */
440: public boolean equals(Object obj) {
441: if (obj instanceof TransactionMetaData) {
442: TransactionMetaData tm = (TransactionMetaData) obj;
443: return tm.getTransactionId() == transactionId;
444: }
445: return false;
446: }
447:
448: /**
449: * @see java.lang.Object#hashCode()
450: */
451: public int hashCode() {
452: return (int) transactionId;
453: }
454: }
|