package com.prolog.cs.biz.inbound.utils;

import com.prolog.framework.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;


/**
 * 结构简单助手
 *
 * @author 鄢菁KingYan
 * @date 2022/04/25
 */
@Slf4j
public class TransactionHelper {


    /**
     * 持久化
     */
    public static Boolean persistence(TransactionFunctional t) {
        DataSourceTransactionManager txManager = TransactionHelper.getTxManager();
        TransactionStatus ts = TransactionHelper.getTransactionStatus(TransactionDefinition.PROPAGATION_REQUIRES_NEW, txManager);
        try {
            t.accept();
            txManager.commit(ts);
        } catch (Exception e) {
            log.error("", e);
            txManager.rollback(ts);
        }
        return true;
    }

    public static Boolean persistenceErrorThrow(TransactionFunctional t) {
        DataSourceTransactionManager txManager = TransactionHelper.getTxManager();
        TransactionStatus ts = TransactionHelper.getTransactionStatus(TransactionDefinition.PROPAGATION_REQUIRES_NEW, txManager);
        try {
            t.accept();
            txManager.commit(ts);
        } catch (Exception e) {
            log.error("", e);
            txManager.rollback(ts);
            throw new RuntimeException(e.getMessage());
        }
        return true;
    }


    private static DataSourceTransactionManager getTxManager() {
        return SpringUtils.getBeansByType(DataSourceTransactionManager.class);
    }


    private static TransactionStatus getTransactionStatus(int propagation, DataSourceTransactionManager manager) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(propagation); // 事物隔离级别，开启新事务.
        return manager.getTransaction(def); // 获得事务状态
    }


    @FunctionalInterface
    public interface TransactionFunctional {
        void accept() throws BizException;
    }

}
