[framework] TxCore → common-framework (ACM-FW-001)
This commit is contained in:
parent
63f85f0f81
commit
2ead4f104a
1 changed files with 96 additions and 0 deletions
|
|
@ -0,0 +1,96 @@
|
|||
package com.klaro.acquirecore.framework;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Transaction template providing @Transactional equivalent functionality.
|
||||
* Migrated from txcore.c tx_begin/tx_commit/tx_rollback functions.
|
||||
*/
|
||||
@Component
|
||||
public class TxTemplate {
|
||||
|
||||
/** Exception thrown when transaction execution fails. */
|
||||
public static class TxExecutionException extends RuntimeException {
|
||||
private final String txId;
|
||||
private final TxContext.TxState state = TxContext.TxState.FAILED;
|
||||
|
||||
public TxExecutionException(String message) { super(message); this.txId = null; }
|
||||
public TxExecutionException(String message, Throwable cause) { super(message, cause); this.txId = null; }
|
||||
public TxExecutionException(String txId, String message) { super(message); this.txId = txId; }
|
||||
public TxExecutionException(String txId, String message, Throwable cause) { super(message, cause); this.txId = txId; }
|
||||
public String getTxId() { return txId; }
|
||||
public TxContext.TxState getState() { return state; }
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private TxServiceRegistry registry;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
|
||||
public TxResult execute(String serviceName, Supplier<Object> action) {
|
||||
return execute(serviceName, new TxConfig(), action);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
|
||||
public TxResult execute(String serviceName, TxConfig config, Supplier<Object> action) {
|
||||
String txId = UUID.randomUUID().toString();
|
||||
TxContext context = new TxContext(txId, serviceName);
|
||||
context.setStartTime(System.currentTimeMillis());
|
||||
context.setState(TxContext.TxState.ACTIVE);
|
||||
try {
|
||||
Object result = action.get();
|
||||
context.setEndTime(System.currentTimeMillis());
|
||||
context.setState(TxContext.TxState.COMMITTED);
|
||||
TxResult txResult = TxResult.ok(txId);
|
||||
txResult.setData(result);
|
||||
txResult.setDurationMs(context.getEndTime() - context.getStartTime());
|
||||
return txResult;
|
||||
} catch (Exception e) {
|
||||
context.setEndTime(System.currentTimeMillis());
|
||||
context.setState(TxContext.TxState.ROLLED_BACK);
|
||||
context.setErrorMessage(e.getMessage());
|
||||
TxResult txResult = TxResult.fail(txId, e.getMessage());
|
||||
txResult.setDurationMs(context.getEndTime() - context.getStartTime());
|
||||
throw new TxExecutionException(txId, "Transaction failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public TxContext begin(String serviceName) {
|
||||
String txId = UUID.randomUUID().toString();
|
||||
TxContext context = new TxContext(txId, serviceName);
|
||||
context.setStartTime(System.currentTimeMillis());
|
||||
context.setState(TxContext.TxState.PENDING);
|
||||
return context;
|
||||
}
|
||||
|
||||
public TxContext begin(String serviceName, TxConfig config) {
|
||||
TxContext context = begin(serviceName);
|
||||
context.setAttribute("config", config);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public TxResult commit(TxContext context) {
|
||||
context.setEndTime(System.currentTimeMillis());
|
||||
context.setState(TxContext.TxState.COMMITTED);
|
||||
return TxResult.ok(context.getTxId());
|
||||
}
|
||||
|
||||
public TxResult rollback(TxContext context, String reason) {
|
||||
context.setEndTime(System.currentTimeMillis());
|
||||
context.setState(TxContext.TxState.ROLLED_BACK);
|
||||
context.setErrorMessage(reason);
|
||||
return TxResult.fail(context.getTxId(), reason);
|
||||
}
|
||||
|
||||
public TxResult executeViaRegistry(String serviceName, TxContext context) {
|
||||
return registry.execute(serviceName, context);
|
||||
}
|
||||
|
||||
public TxServiceRegistry getRegistry() { return registry; }
|
||||
}
|
||||
Reference in a new issue