001: //$Id: CMTTransaction.java 9680 2006-03-22 23:47:31Z epbernard $
002: package org.hibernate.transaction;
003:
004: import javax.transaction.Status;
005: import javax.transaction.Synchronization;
006: import javax.transaction.SystemException;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.hibernate.HibernateException;
011: import org.hibernate.Transaction;
012: import org.hibernate.TransactionException;
013: import org.hibernate.jdbc.JDBCContext;
014: import org.hibernate.util.JTAHelper;
015:
016: /**
017: * Implements a basic transaction strategy for CMT transactions. All work is done
018: * in the context of the container managed transaction.
019: * @author Gavin King
020: */
021: public class CMTTransaction implements Transaction {
022:
023: private static final Log log = LogFactory
024: .getLog(CMTTransaction.class);
025:
026: protected final JDBCContext jdbcContext;
027: protected final TransactionFactory.Context transactionContext;
028:
029: private boolean begun;
030:
031: public CMTTransaction(JDBCContext jdbcContext,
032: TransactionFactory.Context transactionContext) {
033: this .jdbcContext = jdbcContext;
034: this .transactionContext = transactionContext;
035: }
036:
037: public void begin() throws HibernateException {
038: if (begun) {
039: return;
040: }
041:
042: log.debug("begin");
043:
044: boolean synchronization = jdbcContext
045: .registerSynchronizationIfPossible();
046:
047: if (!synchronization) {
048: throw new TransactionException(
049: "Could not register synchronization for container transaction");
050: }
051:
052: begun = true;
053:
054: jdbcContext.afterTransactionBegin(this );
055: }
056:
057: public void commit() throws HibernateException {
058: if (!begun) {
059: throw new TransactionException(
060: "Transaction not successfully started");
061: }
062:
063: log.debug("commit");
064:
065: boolean flush = !transactionContext.isFlushModeNever()
066: && !transactionContext.isFlushBeforeCompletionEnabled();
067:
068: if (flush) {
069: transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
070: }
071:
072: begun = false;
073:
074: }
075:
076: public void rollback() throws HibernateException {
077: if (!begun) {
078: throw new TransactionException(
079: "Transaction not successfully started");
080: }
081:
082: log.debug("rollback");
083:
084: try {
085: getTransaction().setRollbackOnly();
086: } catch (SystemException se) {
087: log.error("Could not set transaction to rollback only", se);
088: throw new TransactionException(
089: "Could not set transaction to rollback only", se);
090: }
091:
092: begun = false;
093:
094: }
095:
096: public javax.transaction.Transaction getTransaction()
097: throws SystemException {
098: return transactionContext.getFactory().getTransactionManager()
099: .getTransaction();
100: }
101:
102: public boolean isActive() throws TransactionException {
103:
104: if (!begun)
105: return false;
106:
107: final int status;
108: try {
109: status = getTransaction().getStatus();
110: } catch (SystemException se) {
111: log.error("Could not determine transaction status", se);
112: throw new TransactionException(
113: "Could not determine transaction status: ", se);
114: }
115: if (status == Status.STATUS_UNKNOWN) {
116: throw new TransactionException(
117: "Could not determine transaction status");
118: } else {
119: return status == Status.STATUS_ACTIVE;
120: }
121: }
122:
123: public boolean wasRolledBack() throws TransactionException {
124:
125: if (!begun)
126: return false;
127:
128: final int status;
129: try {
130: status = getTransaction().getStatus();
131: } catch (SystemException se) {
132: log.error("Could not determine transaction status", se);
133: throw new TransactionException(
134: "Could not determine transaction status", se);
135: }
136: if (status == Status.STATUS_UNKNOWN) {
137: throw new TransactionException(
138: "Could not determine transaction status");
139: } else {
140: return JTAHelper.isRollback(status);
141: }
142: }
143:
144: public boolean wasCommitted() throws TransactionException {
145:
146: if (!begun)
147: return false;
148:
149: final int status;
150: try {
151: status = getTransaction().getStatus();
152: } catch (SystemException se) {
153: log.error("Could not determine transaction status", se);
154: throw new TransactionException(
155: "Could not determine transaction status: ", se);
156: }
157: if (status == Status.STATUS_UNKNOWN) {
158: throw new TransactionException(
159: "Could not determine transaction status");
160: } else {
161: return status == Status.STATUS_COMMITTED;
162: }
163: }
164:
165: public void registerSynchronization(Synchronization sync)
166: throws HibernateException {
167: try {
168: getTransaction().registerSynchronization(sync);
169: } catch (Exception e) {
170: throw new TransactionException(
171: "Could not register synchronization", e);
172: }
173: }
174:
175: public void setTimeout(int seconds) {
176: throw new UnsupportedOperationException(
177: "cannot set transaction timeout in CMT");
178: }
179:
180: }
|