com.evasion.plugin.geoloc.compass.GlassfishSyncTransaction Maven / Gradle / Ivy
The newest version!
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.evasion.plugin.geoloc.compass;
import javax.transaction.*;
import org.compass.core.CompassException;
import org.compass.core.config.CompassEnvironment;
import org.compass.core.spi.InternalCompassSession;
import org.compass.core.transaction.*;
import org.compass.core.CompassSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author sglon
*/
public class GlassfishSyncTransaction extends AbstractTransaction {
private boolean commitBeforeCompletion;
private static final Logger log = LoggerFactory.getLogger(GlassfishSyncTransaction.class);
public GlassfishSyncTransaction(UserTransaction ut, boolean commitBeforeCompletion, TransactionFactory transactionFactory) {
this(ut, transactionFactory);
this.commitBeforeCompletion = commitBeforeCompletion;
}
protected void doBindToTransaction(Transaction tx, InternalCompassSession session, boolean newTransaction) throws Exception {
tx.registerSynchronization(new GlassfishSyncTransaction.JTATransactionSynchronization(session, tx, newTransaction, commitBeforeCompletion, transactionFactory));
}
private static class JTATransactionSynchronization implements Synchronization {
private static final Logger log = LoggerFactory.getLogger(GlassfishSyncTransaction.JTATransactionSynchronization.class);
private InternalCompassSession session;
private Transaction tx;
private boolean compassControlledJtaTransaction;
private boolean commitBeforeCompletion;
private TransactionFactory transactionFactory;
public JTATransactionSynchronization(InternalCompassSession session, Transaction tx,
boolean compassControlledJtaTransaction, boolean commitBeforeCompletion,
TransactionFactory transactionFactory) {
this.session = session;
this.tx = tx;
this.compassControlledJtaTransaction = compassControlledJtaTransaction;
this.commitBeforeCompletion = commitBeforeCompletion;
this.transactionFactory = transactionFactory;
}
public void beforeCompletion() {
if (!commitBeforeCompletion) {
return;
}
if (log.isDebugEnabled()) {
log.debug("Committing compass transaction using JTA synchronization beforeCompletion on thread ["
+ Thread.currentThread().getName() + "]");
}
session.getSearchEngine().commit(true);
}
public void afterCompletion(int status) {
try {
if (!commitBeforeCompletion) {
if (status == Status.STATUS_COMMITTED) {
if (log.isDebugEnabled()) {
log.debug("Committing compass transaction using JTA synchronization afterCompletion on thread ["
+ Thread.currentThread().getName() + "]");
}
session.getSearchEngine().commit(true);
} else {
if (log.isDebugEnabled()) {
log.debug("Rolling back compass transaction using JTA synchronization afterCompletion on thread ["
+ Thread.currentThread().getName() + "] with status [" + status + "]");
}
session.getSearchEngine().rollback();
}
}
} catch (Exception e) {
// TODO swallow??????
log.error("Exception occured when sync with transaction", e);
} finally {
session.evictAll();
((JTASyncTransactionFactory) transactionFactory).unbindSessionFromTransaction(tx, session);
// close the session AFTER we cleared it from the transaction,
// so it will be actually closed (and only if we are not
// controlling the trnasction)
if (!compassControlledJtaTransaction) {
session.close();
}
}
}
}
private UserTransaction ut;
/**
* Did we start the JTA transaction
*/
private boolean newTransaction;
/**
* Is this the up most level controlling the Compass transaction
*/
private boolean controllingNewTransaction = false;
private boolean commitFailed;
private InternalCompassSession session;
public GlassfishSyncTransaction(UserTransaction ut, TransactionFactory transactionFactory) {
super(transactionFactory);
this.ut = ut;
}
public void begin(InternalCompassSession session, TransactionManager transactionManager) throws CompassException {
try {
this.session = session;
controllingNewTransaction = true;
try {
newTransaction = ut.getStatus() == Status.STATUS_NO_TRANSACTION;
} catch (IllegalStateException ex) {
newTransaction = false;
}
if (newTransaction) {
if (log.isDebugEnabled()) {
log.debug("Beginning new JTA transaction, and a new compass transaction on thread ["
+ Thread.currentThread().getName() + "]");
}
session.getSearchEngine().begin();
int timeout = session.getSettings().getSettingAsInt(CompassEnvironment.Transaction.TRANSACTION_TIMEOUT, -1);
if (timeout != -1) {
ut.setTransactionTimeout(timeout);
}
ut.begin();
} else {
// joining an exisiting transaction
session.getSearchEngine().begin();
if (log.isDebugEnabled()) {
log.debug("Joining an existing JTA transaction, starting a new compass transaction on thread ["
+ Thread.currentThread().getName() + "]");
}
}
javax.transaction.Transaction tx = transactionManager.getTransaction();
doBindToTransaction(tx, session, newTransaction);
} catch (Exception e) {
throw new TransactionException("Begin failed with exception", e);
}
setBegun(true);
}
/**
* Called by the factory when joining an already running compass transaction
*/
public void join(InternalCompassSession session) throws CompassException {
this.session = session;
controllingNewTransaction = false;
if (log.isDebugEnabled()) {
log.debug("Joining an existing compass transcation on thread [" + Thread.currentThread().getName() + "]");
}
}
protected void doCommit() throws CompassException {
if (!controllingNewTransaction) {
if (log.isDebugEnabled()) {
log.debug("Not committing JTA transaction since compass does not control it on thread ["
+ Thread.currentThread().getName() + "]");
}
return;
}
if (newTransaction) {
if (log.isDebugEnabled()) {
log.debug("Committing JTA transaction controlled by compass on thread ["
+ Thread.currentThread().getName() + "]");
}
try {
ut.commit();
} catch (Exception e) {
commitFailed = true;
// so the transaction is already rolled back, by JTA spec
throw new TransactionException("Commit failed", e);
}
} else {
if (log.isDebugEnabled()) {
log.debug("Commit called, let JTA synchronization commit the transaciton on thread ["
+ Thread.currentThread().getName() + "]");
}
}
}
protected void doRollback() throws CompassException {
try {
if (newTransaction) {
if (log.isDebugEnabled()) {
log.debug("Rolling back JTA transaction controlled by compass on thread [" + Thread.currentThread().getName() + "]");
}
if (!commitFailed) {
ut.rollback();
}
} else {
if (log.isDebugEnabled()) {
log.debug("Marking JTA transaction as rolled back since compass controlls it on thread ["
+ Thread.currentThread().getName() + "]");
}
ut.setRollbackOnly();
}
} catch (Exception e) {
throw new TransactionException("Rollback failed with exception", e);
}
}
public boolean wasRolledBack() throws TransactionException {
if (!isBegun()) {
return false;
}
if (commitFailed) {
return true;
}
final int status;
try {
status = ut.getStatus();
} catch (SystemException se) {
throw new TransactionException("Could not determine transaction status", se);
}
if (status == Status.STATUS_UNKNOWN) {
throw new TransactionException("Could not determine transaction status");
} else {
return status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLING_BACK
|| status == Status.STATUS_ROLLEDBACK;
}
}
public boolean wasCommitted() throws TransactionException {
if (!isBegun() || commitFailed) {
return false;
}
final int status;
try {
status = ut.getStatus();
} catch (SystemException se) {
throw new TransactionException("Could not determine transaction status: ", se);
}
if (status == Status.STATUS_UNKNOWN) {
throw new TransactionException("Could not determine transaction status");
} else {
return status == Status.STATUS_COMMITTED;
}
}
public CompassSession getSession() {
return this.session;
}
}