diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxTemplate.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxTemplate.java new file mode 100644 index 0000000..a831ed2 --- /dev/null +++ b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/TxTemplate.java @@ -0,0 +1,74 @@ +package com.klaro.acquirecore.framework; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * Transaction template replacing C tx_begin/tx_commit pattern. + * Provides @Transactional-backed execution with context management. + * Mirrors C tx_begin(), tx_commit(), tx_rollback() lifecycle. + */ +@Component +public class TxTemplate { + + /** + * Execute a transactional operation with automatic commit on success, + * rollback on exception. Mirrors C tx_begin + tx_commit pattern. + * + * @param serviceName the name of the registered service + * @param input the input data + * @param the result type + * @return TxResult containing the outcome + */ + @Transactional(rollbackFor = Exception.class) + public TxResult execute(String serviceName, Object input) { + return executeWithContext(serviceName, new TxContext(serviceName), input); + } + + /** + * Execute with an existing transaction context. + * + * @param serviceName the name of the registered service + * @param ctx the existing transaction context + * @param input the input data + * @param the result type + * @return TxResult containing the outcome + */ + @Transactional(rollbackFor = Exception.class) + public TxResult executeWithContext(String serviceName, TxContext ctx, Object input) { + ctx.setStatus(TxStatus.ACTIVE); + try { + Object result = doExecute(serviceName, ctx, input); + ctx.markCommitted(); + return TxResult.ok(result); + } catch (Exception e) { + ctx.markRolledBack(); + return TxResult.error("TX_FAILED", e.getMessage()); + } + } + + /** + * Execute without transaction boundary (read-only operations). + * + * @param serviceName the name of the registered service + * @param input the input data + * @param the result type + * @return TxResult containing the outcome + */ + @Transactional(readOnly = true) + public TxResult query(String serviceName, Object input) { + try { + TxContext ctx = new TxContext(serviceName); + Object result = doExecute(serviceName, ctx, input); + return TxResult.ok(result); + } catch (Exception e) { + return TxResult.error("QUERY_FAILED", e.getMessage()); + } + } + + private Object doExecute(String serviceName, TxContext ctx, Object input) { + throw new UnsupportedOperationException( + "Direct execution not supported. Use TxServiceRegistry.dispatch() or inject TxService directly." + ); + } +}