de.thksystems.container.spring.BaseService Maven / Gradle / Ivy
/*
* tksCommons / mugwort
*
* Author : Thomas Kuhlmann (ThK-Systems, http://oss.thk-systems.de) License : LGPL (https://www.gnu.org/licenses/lgpl.html)
*/
package de.thksystems.container.spring;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import de.thksystems.exception.ServiceRuntimeException;
public abstract class BaseService {
private final static Logger LOG = LoggerFactory.getLogger(BaseService.class);
@Autowired
private PlatformTransactionManager transactionManager;
/**
* Throws given exception as {@link ServiceRuntimeException}.
*/
protected T throwAsServiceRuntimeExceptionAndLog(Throwable cause, String message) {
String msg = message + ": " + cause.toString();
LOG.error(msg, cause);
throw new ServiceRuntimeException(msg, cause);
}
/**
* Start transaction manually.
*
* Use it with caution!
* Do not mix annotation based transaction handling and programmatically one!
* Do not call any repository method before starting a transaction. (It seems an implicit transaction is created.)
*
* @param readonly
* For readonly transactions.
*/
protected TransactionStatus startTransaction(boolean readonly) {
LOG.trace("Starting new transaction");
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(readonly);
return transactionManager.getTransaction(transactionDefinition);
}
protected TransactionStatus startTransaction() {
return startTransaction(false);
}
/**
* Start transacation manually, if required.
*
* @see #startTransaction()
*/
protected TransactionStatus startTransactionIfRequired(TransactionStatus transactionStatus) {
if (transactionStatus == null || transactionStatus.isCompleted()) {
return startTransaction();
}
return transactionStatus;
}
/**
* Commit transaction manually.
*
* If the transaction is set rollbackOnly, a rollback is done.
*
* @see #startTransaction() for notes and warning.
*/
protected void commitTransaction(TransactionStatus transactionStatus) {
if (transactionStatus != null && !transactionStatus.isCompleted()) {
if (transactionStatus.isRollbackOnly()) {
LOG.trace("Transaction is set rollback only.");
rollbackTransaction(transactionStatus);
} else {
LOG.trace("Transaction commited");
transactionManager.commit(transactionStatus);
}
}
}
/**
* Rollback transaction manually.
*
* @see #startTransaction() for notes and warning.
*/
protected void rollbackTransaction(TransactionStatus transactionStatus) {
if (transactionStatus != null && !transactionStatus.isCompleted()) {
LOG.trace("Transaction rollbacked.");
transactionManager.rollback(transactionStatus);
}
}
/**
* Returns true
, if scheduling, should be enabled.
*/
protected boolean enableScheduling() {
return !isJUnitTest();
}
/**
* Returns true
, if we are running in the context of a junit-test.
*
* @see Source: http://stackoverflow.com/a/12717377/1869090
*/
private boolean isJUnitTest() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
List list = Arrays.asList(stackTrace);
for (StackTraceElement element : list) {
if (element.getClassName().startsWith("org.junit.")) {
return true;
}
}
return false;
}
}