001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.mq.pm;
023:
024: import java.io.Externalizable;
025: import java.util.ArrayList;
026:
027: import javax.jms.JMSException;
028: import javax.transaction.xa.Xid;
029:
030: /**
031: * A transaction
032: *
033: * @author <a href="mailto:adrian@jboss.org">Adrian Brock</a>
034: * @version $Revision: 57198 $
035: */
036: public class Tx implements Comparable, Externalizable {
037: /** The serialVersionUID */
038: static final long serialVersionUID = -5428592493990463362L;
039:
040: /** Transaction open */
041: private static final int OPEN = 0;
042: /** Transaction ended */
043: private static final int ENDED = 2;
044:
045: /** Restore unknown */
046: public static final int UNKNOWN = 0;
047:
048: /** Restore addition */
049: public static final int ADD = 1;
050:
051: /** Restore remove */
052: public static final int REMOVE = -1;
053:
054: /** The transaction value */
055: long value = 0;
056:
057: /** Whether the transaction has been persisted */
058: boolean persisted = false;
059:
060: transient Xid xid;
061:
062: /** List of Runnable tasks */
063: transient ArrayList postCommitTasks;
064: /** List of Runnable tasks */
065: transient ArrayList postRollbackTasks;
066:
067: /** The status */
068: transient int status = OPEN;
069:
070: /** The lock */
071: transient Object lock = new Object();
072:
073: /**
074: * Create a new Tx for externailzation
075: */
076: public Tx() {
077: }
078:
079: /**
080: * Create a new Tx
081: *
082: * @param value the value
083: */
084: public Tx(long value) {
085: this .value = value;
086: }
087:
088: /**
089: * Set the value
090: *
091: * @param tx the new value
092: */
093: public void setValue(long tx) {
094: value = tx;
095: }
096:
097: /**
098: * Get the long value
099: *
100: * @return the long value
101: */
102: public long longValue() {
103: return value;
104: }
105:
106: /**
107: * Get the xid.
108: *
109: * @return the xid.
110: */
111: public Xid getXid() {
112: return xid;
113: }
114:
115: /**
116: * Set the xid.
117: *
118: * @param xid the xid.
119: */
120: public void setXid(Xid xid) {
121: this .xid = xid;
122: }
123:
124: /**
125: * Get whether the transaction has been persisted
126: *
127: * @return true when persisted
128: */
129: public synchronized boolean checkPersisted() {
130: boolean result = persisted;
131: persisted = true;
132: return result;
133: }
134:
135: /**
136: * Get whether the transaction has been persisted
137: *
138: * @return true when persisted
139: */
140: public synchronized boolean wasPersisted() {
141: return persisted;
142: }
143:
144: /**
145: * Compare
146: *
147: * @param anotherLong the other value
148: * @return -1, 0, 1 if less than, equal or greater than respectively
149: */
150: public int compareTo(Tx anotherLong) {
151: long this Val = this .value;
152: long anotherVal = anotherLong.value;
153: return (this Val < anotherVal ? -1 : (this Val == anotherVal ? 0
154: : 1));
155: }
156:
157: public int compareTo(Object o) {
158: return compareTo((Tx) o);
159: }
160:
161: public void readExternal(java.io.ObjectInput in)
162: throws java.io.IOException {
163: value = in.readLong();
164: }
165:
166: public void writeExternal(java.io.ObjectOutput out)
167: throws java.io.IOException {
168: out.writeLong(value);
169: }
170:
171: public String toString() {
172: return String.valueOf(value);
173: }
174:
175: public int hashCode() {
176: return (int) (value ^ (value >> 32));
177: }
178:
179: /**
180: * Commit the transaction
181: *
182: * @param pm the persistence manager
183: * @throws JMSExecption for any error
184: */
185: void commit(PersistenceManager pm) throws JMSException {
186: synchronized (lock) {
187: if (status == ENDED)
188: throw new JMSException(
189: "Transaction is not active for commit");
190: status = ENDED;
191: postRollbackTasks = null;
192: }
193:
194: pm.commitPersistentTx(this );
195:
196: synchronized (lock) {
197: if (postCommitTasks == null)
198: return;
199:
200: for (int i = 0; i < postCommitTasks.size(); ++i) {
201: Runnable task = (Runnable) postCommitTasks.get(i);
202: task.run();
203: }
204:
205: postCommitTasks = null;
206: }
207: }
208:
209: /**
210: * Add post commit task
211: *
212: * @param task the task
213: * @throws JMSExecption for any error
214: */
215: void addPostCommitTask(Runnable task) throws JMSException {
216: synchronized (lock) {
217: if (status == ENDED)
218: throw new JMSException("Transacation is not active.");
219: if (postCommitTasks == null)
220: postCommitTasks = new ArrayList();
221: postCommitTasks.add(task);
222: }
223: }
224:
225: /**
226: * Commit the transaction
227: *
228: * @param pm the persistence manager
229: * @throws JMSExecption for any error
230: */
231: public void rollback(PersistenceManager pm) throws JMSException {
232: synchronized (lock) {
233: if (status == ENDED)
234: throw new JMSException(
235: "Transaction is not active for rollback");
236: status = ENDED;
237: postCommitTasks = null;
238: }
239:
240: pm.rollbackPersistentTx(this );
241:
242: synchronized (lock) {
243: if (postRollbackTasks == null)
244: return;
245:
246: for (int i = 0; i < postRollbackTasks.size(); ++i) {
247: Runnable task = (Runnable) postRollbackTasks.get(i);
248: task.run();
249: }
250:
251: postRollbackTasks = null;
252: }
253: }
254:
255: /**
256: * Add post rollback task
257: *
258: * @param task the task
259: * @throws JMSExecption for any error
260: */
261: public void addPostRollbackTask(Runnable task) throws JMSException {
262: synchronized (lock) {
263: if (status == ENDED)
264: throw new JMSException("Transacation is not active.");
265: if (postRollbackTasks == null)
266: postRollbackTasks = new ArrayList();
267: postRollbackTasks.add(task);
268: }
269: }
270: }
|