package com.revolsys.transaction;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.revolsys.io.BaseCloseable;
import com.revolsys.util.Exceptions;
public class Transaction implements BaseCloseable {
private static ThreadLocal<Transaction> currentTransaction = new ThreadLocal<>();
public static void afterCommit(final Runnable runnable) {
if (runnable != null) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
final RunnableAfterCommit synchronization = new RunnableAfterCommit(runnable);
TransactionSynchronizationManager.registerSynchronization(synchronization);
} else {
runnable.run();
}
}
}
public static Transaction getCurrentTransaction() {
return currentTransaction.get();
}
public static boolean isHasCurrentTransaction() {
return getCurrentTransaction() != null;
}
public static Runnable runnable(final Runnable runnable,
final PlatformTransactionManager transactionManager, final Propagation propagation) {
if (transactionManager == null || propagation == null) {
return runnable;
} else {
final DefaultTransactionDefinition transactionDefinition = Transaction
.transactionDefinition(propagation);
return new TransactionRunnable(transactionManager, transactionDefinition, runnable);
}
}
public static void setCurrentRollbackOnly() {
final Transaction transaction = currentTransaction.get();
if (transaction != null) {
transaction.setRollbackOnly();
}
}
public static DefaultTransactionDefinition transactionDefinition(final Propagation propagation) {
if (propagation == null) {
return null;
} else {
final int propagationValue = propagation.value();
final DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(
propagationValue);
return transactionDefinition;
}
}
public static DefaultTransactionStatus transactionStatus(
final PlatformTransactionManager transactionManager, final Propagation propagation) {
if (propagation == null || transactionManager == null) {
return null;
} else {
final DefaultTransactionDefinition transactionDefinition = transactionDefinition(propagation);
return transactionStatus(transactionManager, transactionDefinition);
}
}
public static DefaultTransactionStatus transactionStatus(
final PlatformTransactionManager transactionManager,
final TransactionDefinition transactionDefinition) {
if (transactionManager == null || transactionDefinition == null) {
return null;
} else {
return (DefaultTransactionStatus)transactionManager.getTransaction(transactionDefinition);
}
}
private Transaction previousTransaction;
private PlatformTransactionManager transactionManager;
private DefaultTransactionStatus transactionStatus;
public Transaction(final PlatformTransactionManager transactionManager) {
this(transactionManager, Propagation.REQUIRES_NEW);
}
public Transaction(final PlatformTransactionManager transactionManager,
final DefaultTransactionStatus transactionStatus) {
this.transactionManager = transactionManager;
if (transactionManager == null) {
this.transactionStatus = null;
} else {
this.transactionStatus = transactionStatus;
}
this.previousTransaction = getCurrentTransaction();
currentTransaction.set(this);
}
public Transaction(final PlatformTransactionManager transactionManager,
final Propagation propagation) {
this(transactionManager, Transaction.transactionStatus(transactionManager, propagation));
}
public Transaction(final PlatformTransactionManager transactionManager,
final TransactionDefinition transactionDefinition) {
this(transactionManager, transactionStatus(transactionManager, transactionDefinition));
}
@Override
public void close() throws RuntimeException {
commit();
currentTransaction.set(this.previousTransaction);
this.transactionManager = null;
this.previousTransaction = null;
this.transactionStatus = null;
}
protected void commit() {
if (this.transactionManager != null && this.transactionStatus != null) {
if (!this.transactionStatus.isCompleted()) {
if (this.transactionStatus.isRollbackOnly()) {
rollback();
} else {
try {
this.transactionManager.commit(this.transactionStatus);
} catch (final Throwable e) {
Exceptions.throwUncheckedException(e);
}
}
}
}
}
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
public DefaultTransactionStatus getTransactionStatus() {
return this.transactionStatus;
}
public boolean isCompleted() {
if (this.transactionStatus == null) {
return true;
} else {
return this.transactionStatus.isCompleted();
}
}
public boolean isRollbackOnly() {
return this.transactionStatus.isRollbackOnly();
}
protected void rollback() {
if (this.transactionManager != null && this.transactionStatus != null) {
this.transactionManager.rollback(this.transactionStatus);
}
}
public void setRollbackOnly() {
if (this.transactionStatus != null) {
this.transactionStatus.setRollbackOnly();
}
}
public RuntimeException setRollbackOnly(final Throwable e) {
setRollbackOnly();
return Exceptions.throwUncheckedException(e);
}
}