001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.transaction;
018:
019: import javax.transaction.Status;
020: import javax.transaction.Synchronization;
021: import javax.transaction.Transaction;
022: import javax.transaction.UserTransaction;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.compass.core.spi.InternalCompassSession;
027:
028: /**
029: * Implements a basic transaction strategy for JTA transactions. Instances check
030: * to see if there is an existing JTA transaction. If none exists, a new
031: * transaction is started. If one exists, all work is done in the existing
032: * context.
033: *
034: * @author kimchy
035: */
036: public class JTASyncTransaction extends AbstractJTATransaction {
037:
038: private boolean commitBeforeCompletion;
039:
040: public JTASyncTransaction(UserTransaction ut,
041: boolean commitBeforeCompletion,
042: TransactionFactory transactionFactory) {
043: super (ut, transactionFactory);
044: this .commitBeforeCompletion = commitBeforeCompletion;
045: }
046:
047: protected void doBindToTransaction(Transaction tx,
048: InternalCompassSession session, boolean newTransaction)
049: throws Exception {
050: tx.registerSynchronization(new JTATransactionSynchronization(
051: session, tx, newTransaction, commitBeforeCompletion,
052: transactionFactory));
053: }
054:
055: private static class JTATransactionSynchronization implements
056: Synchronization {
057:
058: private static final Log log = LogFactory
059: .getLog(JTATransactionSynchronization.class);
060:
061: private InternalCompassSession session;
062:
063: private Transaction tx;
064:
065: private boolean compassControlledJtaTransaction;
066:
067: private boolean commitBeforeCompletion;
068:
069: private TransactionFactory transactionFactory;
070:
071: public JTATransactionSynchronization(
072: InternalCompassSession session, Transaction tx,
073: boolean compassControlledJtaTransaction,
074: boolean commitBeforeCompletion,
075: TransactionFactory transactionFactory) {
076: this .session = session;
077: this .tx = tx;
078: this .compassControlledJtaTransaction = compassControlledJtaTransaction;
079: this .commitBeforeCompletion = commitBeforeCompletion;
080: this .transactionFactory = transactionFactory;
081: }
082:
083: public void beforeCompletion() {
084: if (!commitBeforeCompletion) {
085: return;
086: }
087: if (log.isDebugEnabled()) {
088: log
089: .debug("Committing compass transaction using JTA synchronization beforeCompletion on thread ["
090: + Thread.currentThread().getName()
091: + "]");
092: }
093: session.getSearchEngine().commit(true);
094: }
095:
096: public void afterCompletion(int status) {
097: try {
098: if (!commitBeforeCompletion) {
099: if (status == Status.STATUS_COMMITTED) {
100: if (log.isDebugEnabled()) {
101: log
102: .debug("Committing compass transaction using JTA synchronization afterCompletion on thread ["
103: + Thread.currentThread()
104: .getName() + "]");
105: }
106: session.getSearchEngine().commit(true);
107: } else {
108: if (log.isDebugEnabled()) {
109: log
110: .debug("Rolling back compass transaction using JTA synchronization afterCompletion on thread ["
111: + Thread.currentThread()
112: .getName()
113: + "] with status ["
114: + status + "]");
115: }
116: session.getSearchEngine().rollback();
117: }
118: }
119: } catch (Exception e) {
120: // TODO swallow??????
121: log.error(
122: "Exception occured when sync with transaction",
123: e);
124: } finally {
125: session.evictAll();
126: ((JTASyncTransactionFactory) transactionFactory)
127: .unbindSessionFromTransaction(tx);
128: // close the session AFTER we cleared it from the transaction,
129: // so it will be actually closed (and only if we are not
130: // controlling the trnasction)
131: if (!compassControlledJtaTransaction) {
132: session.close();
133: }
134: }
135: }
136: }
137:
138: }
|