ThreadLocal实战之数据库执行器线程同步

128 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

前言

近来,在框架中获取数据库执行器时,一直通过参数传递,颇觉繁琐,且不符合设计常理。

故而,思虑片刻,欲将其融入至笔者框架内置的“RequestAttributes”对象中。

此属性对象采用“ThreadLocal”作为线程局部变量同步。

以下是具体的流转思路图

WeChatb8262aaf931a3df8b1b23601daa2436e.png

基于以上思路,笔者先创建“ExecutorAttributes”类,将其定义为数据库执行器属性类,并定义“泛型”用于子类实现后可以通过“链式”调用其中内置函数。

其中,内置“数据库执行器”,“是否打开事务”,“是否提交事务”等一些基础函数。

以下,是具体的实现代码

package com.threeox.drivenlibrary.context.attr;

import com.threeox.dblibrary.executor.inter.ISqlExecutor;
import com.threeox.drivenlibrary.enums.ResponseResult;
import com.threeox.drivenlibrary.exception.ResponseException;
import com.threeox.utillibrary.logger.LoggerFactory;

/**
 * 数据库执行器属性
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/6/29 21:27
 */
public class ExecutorAttributes<T> {

    protected static final LoggerFactory logger = LoggerFactory.getLogger(ExecutorAttributes.class.getName());

    /**
     * 数据库执行器
     */
    private ISqlExecutor executor;
    /**
     * 是否打开事务
     */
    private boolean isStartTransaction = false;
    /**
     * 是否提交事务
     */
    private boolean isSubmitTransaction = true;

    /**
     * 设置是否开启事务
     *
     * @param startTransaction
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 21:33
     * @version 1.0
     */
    public T setStartTransaction(boolean startTransaction) {
        isStartTransaction = startTransaction;
        return (T) this;
    }

    /**
     * 设置是否提交事务
     *
     * @param submitTransaction
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 21:33
     * @version 1.0
     */
    public T setSubmitTransaction(boolean submitTransaction) {
        isSubmitTransaction = submitTransaction;
        return (T) this;
    }

    /**
     * 设置执行器
     *
     * @param executor
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 21:34
     * @version 1.0
     */
    public T setExecutor(ISqlExecutor executor) {
        this.executor = executor;
        return (T) this;
    }

    /**
     * 获取数据库执行器
     *
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 21:56
     * @version 1.0
     */
    public ISqlExecutor getExecutor() {
        return executor;
    }

    /**
     * 开启事务
     *
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 21:39
     * @version 1.0
     */
    public T beginTransaction() throws Exception {
        if (isStartTransaction && executor != null) {
            executor.beginTransaction();
        }
        return (T) this;
    }

    /**
     * 提交事务
     *
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 22:24
     * @version 1.0
     */
    public T commit() throws ResponseException {
        try {
            if (isStartTransaction && executor != null) {
                if (isSubmitTransaction) {
                    // 提交事务
                    executor.commit();
                } else {
                    // 回退事务
                    executor.rollback();
                }
            }
        } catch (Exception e) {
            logger.error("提交事务异常", e);
            throw ResponseException.newInstance(ResponseResult.TRANSACTION_ABNORMAL);
        }
        return (T) this;
    }

    /**
     * 回退事务
     *
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/6/29 21:48
     * @version 1.0
     */
    public T rollback() {
        try {
            if (isStartTransaction && executor != null) {
                executor.rollback();
            }
        } catch (Exception e1) {
            logger.error("回退事务异常", e1);
        }
        return (T) this;
    }
}

继而,使此前实现的“RequestAttributes”继承此类,并实现相应处理逻辑

package com.threeox.drivenlibrary.context.attr;

import com.alibaba.fastjson.JSONObject;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 请求属性对象
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/4/18 23:56
 */
public class RequestAttributes extends ExecutorAttributes<RequestAttributes> {

    /**
     * 泛型参数对象
     */
    private Object requestParams;
    /**
     * json 请求参数
     */
    private JSONObject paramsJSON;
    /**
     * request
     */
    private HttpServletRequest request;
    /**
     * response
     */
    private HttpServletResponse response;

    /**
     * api属性
     */
    private ApiAttributes apiAttributes;
    /**
     * 功能属性
     */
    private FuncAttributes funcAttributes;

    public static RequestAttributes builder(HttpServletRequest request, HttpServletResponse response) {
        return new RequestAttributes(request, response);
    }

    private RequestAttributes() {
    }

    public RequestAttributes(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    public <T extends Object> T getRequestParams() {
        return (T) requestParams;
    }

    public JSONObject getParamsJSON() {
        return paramsJSON;
    }

    public RequestAttributes setParamsJSON(JSONObject paramsJSON, Class paramsClass) {
        this.paramsJSON = paramsJSON;
        if (paramsJSON != null) {
            // 获取请求参数泛型对象
            if (paramsClass != null) {
                requestParams = paramsJSON.toJavaObject(paramsClass);
            } else {
                requestParams = paramsJSON;
            }
        }
        return this;
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    /**
     * 获取功能属性
     *
     * @author 赵屈犇
     * @return
     * @date 2022/4/20 22:56
     */
    public FuncAttributes func() {
        if (funcAttributes == null) {
            funcAttributes = new FuncAttributes();
        }
        return funcAttributes;
    }

    /**
     * 获取api属性
     *
     * @author 赵屈犇
     * @return
     * @date 2022/4/21 21:45
     */
    public ApiAttributes api() {
        if (apiAttributes == null) {
            apiAttributes = new ApiAttributes();
        }
        return apiAttributes;
    }

}

至此,属性对象已成功定义,笔者只需在具体的实现逻辑,调用早前封装的“RequestContextHolder”类,进行数据库执行器相关操作,以“元素事件”请求为例

WeChat1a38d1c3f0f2232ef5e0fc764421455b.png 综上,已实现所有功能,接下来就需要验证一下功能是否完整。此下视频,是详细的功能实现结果。

由于不能上传视频,跳转观看实现效果