com.sap.cds.framework.spring.transaction.SpringTransactionManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cds-framework-spring-boot Show documentation
Show all versions of cds-framework-spring-boot Show documentation
Integration into the Spring Boot framework for CDS Services Java
/*********************************************************************
* (C) 2019 SAP SE or an SAP affiliate company. All rights reserved. *
*********************************************************************/
package com.sap.cds.framework.spring.transaction;
import java.util.Stack;
import java.util.UUID;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.sap.cds.services.transaction.TransactionManager;
public class SpringTransactionManager implements TransactionManager {
private final PlatformTransactionManager txMgr;
private final ThreadLocal> transactions = ThreadLocal.withInitial(() -> new Stack<>());
private final String name = "spring-" + UUID.randomUUID().toString();
public SpringTransactionManager(PlatformTransactionManager txMgr) {
this.txMgr = txMgr;
}
@Override
public boolean isActive() {
// check global transaction flag and not only transactions managed by us
return TransactionSynchronizationManager.isActualTransactionActive();
}
@Override
public void begin() {
// Transactions started before the ChangeSet scope are OK
// -> ChangeSetContext defines new "Requires New" boundaries
// Transactions started within the ChangeSet scope but after this begin are OK
// -> Transactions take part in opened transaction (Requires)
// Transactions started within the ChangeSet scope but before this begin are OK
// -> begin is called by the proxy, if transaction with "Requires" is opened
// !!! Additional "Requires New" might cut the ChangeSet in parts!
DefaultTransactionDefinition definition = new DefaultTransactionDefinition(
TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactions.get().push(txMgr.getTransaction(definition));
}
@Override
public void commit() {
txMgr.commit(transactions.get().pop());
}
@Override
public void rollback() {
txMgr.rollback(transactions.get().pop());
}
@Override
public boolean isRollbackOnly() {
return transactions.get().peek().isRollbackOnly();
}
@Override
public void setRollbackOnly() {
// works only for transactions opened by @Transactional annotations
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
@Override
public String getName() {
return name;
}
}