无事务运行代码原创
3人赞赏了该文章
1,214次浏览
编辑于2022年05月14日 11:21:15
事务相关知识请查看 事务的四种隔离级别和七种传播机制
有时需要在操作插件(AbstractOperationServicePlugIn)的beginOperationTransaction和endOperationTransaction方法中执行一些事务外的逻辑,比如主操作没有执行成功,但是需要向将日志等信息存入数据库中,此时可以使用以下工具类实现无事务运行代码。
import kd.bos.db.tx.TX; import kd.bos.db.tx.TXHandle; import kd.bos.exception.ErrorCode; import kd.bos.exception.KDException; import kd.bos.logging.Log; import kd.bos.logging.LogFactory; import java.util.function.*; /** * 事务相关工具类 * * @author lzpeng * @version 1.0 * @date 2022/1/4 12:15 */ public final class TxUtils { private static final Log log = LogFactory.getLog(TxUtils.class); /** * 无事务运行 * * @param runnable runnable * @return 执行结果 */ public static void executeNoTx(Runnable runnable) { executeNoTx((Consumer<TXHandle>) txHandle -> runnable.run()); } /** * 无事务运行 * * @param supplier Supplier * @param <T> * @return 执行结果 */ public static <T> T executeNoTx(Supplier<T> supplier) { return executeNoTx((Function<TXHandle, ? extends T>) notTx -> supplier.get()); } /** * 无事务运行 * * @param consumer */ public static void executeNoTx(Consumer<TXHandle> consumer) { executeNoTx((BiConsumer<TXHandle, TXHandle>) (txHandle, notTx) -> consumer.accept(notTx)); } /** * 无事务运行 * * @param biConsumer */ public static void executeNoTx(BiConsumer<TXHandle, TXHandle> biConsumer) { executeNoTx((BiFunction<TXHandle, TXHandle, Void>) (txHandle, notTx) -> { biConsumer.accept(txHandle, notTx); return null; }); } /** * 无事务运行 * * @param function * @param <T> * @return 执行结果 */ public static <T> T executeNoTx(Function<TXHandle, T> function) { return executeNoTx((BiFunction<TXHandle, TXHandle, ? extends T>) (txHandle, notTx) -> function.apply(notTx)); } /** * 无事务运行 * * @param biFunction * @param <T> * @return 执行结果 */ public static <T> T executeNoTx(BiFunction<TXHandle, TXHandle, T> biFunction) { return executeWithTX(txHandle -> { try (TXHandle notTx = TX.notSupported()) { return biFunction.apply(txHandle, notTx); } }); } /** * 有事务运行 * * @param runnable runnable * @return 执行结果 */ public static void executeWithTX(Runnable runnable) { executeWithTX((Consumer<TXHandle>) txHandle -> runnable.run()); } /** * 有事务运行 * * @param supplier * @param <T> * @return 执行结果 */ public static <T> T executeWithTX(Supplier<T> supplier) { return executeWithTX((Function<TXHandle, ? extends T>) txHandle -> supplier.get()); } /** * 有事务运行 * * @param consumer */ public static void executeWithTX(Consumer<TXHandle> consumer) { executeWithTX((Function<TXHandle, Void>) txHandle -> { consumer.accept(txHandle); return null; }); } /** * 有事务运行 * * @param function * @param <T> * @return 执行结果 */ public static <T> T executeWithTX(Function<TXHandle, T> function) { try (TXHandle txHandle = TX.requiresNew()) { try { return function.apply(txHandle); } catch (Exception e) { txHandle.markRollback(); throw wrapKDException(e); } } } /** * 包装为 KDException * * @param e 异常 * @return */ private static KDException wrapKDException(Throwable e) { log.error(e); if (e instanceof KDException) { return (KDException) e; } return new KDException(e, new ErrorCode("TXException", e.getMessage())); } /** * 抛出 KDException * * @param e 异常 * @return */ private static KDException throwKDException(Throwable e) { throw wrapKDException(e); } }
使用方式
import org.junit.Test; /** * @author lzpeng * @version 1.0 * @date 2022/5/14 10:34 */ public class TxUtilsTest { /** * 测试无事务运行 */ @Test public void testExecuteNoTx() { TxUtils.executeNoTx(() -> {}); TxUtils.executeNoTx(() -> null); TxUtils.executeNoTx(tx -> {}); TxUtils.executeNoTx(tx -> tx); TxUtils.executeNoTx((tx1,tx2) -> {}); TxUtils.executeNoTx((tx1,tx2) -> null); } /** * 测试有事务运行 */ @Test public void testExecuteWithTX() { TxUtils.executeWithTX(() -> {}); TxUtils.executeWithTX(() -> null); TxUtils.executeWithTX(tx -> {}); TxUtils.executeWithTX(tx -> tx); } }