异步往数据库中插入每个用户的增删改操作日志

版权声明:作者: Daley Zou ( https://blog.csdn.net/DaleyZou ) 出处: https://blog.csdn.net/DaleyZou/article/details/85339362
  • ++我们需要一个工具类++

用工具类异步向数据库中插入用户的操作日志

工具类代码如下:
package com.dp.api.util;

import com.dp.common.dao.DaoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.model.TSysUpdateLog;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @Author: DaleyZou
 * @Description: 用于向数据库中写入操作日志,十个数据写一条记录
 * @Date: Created in 14:56 2018/12/28
 * @Modified By:
 */
@Service
public class OperationLogSaver {

    protected static Logger logger = LoggerFactory.getLogger(OperationLogSaver.class);

//    @Autowired
//    private TSysUpdateLogMapper tSysUpdateLogMapper;

    @Autowired
    private DaoUtil daoUtil;
    private LinkedBlockingQueue<TSysUpdateLog> queue;

    private static int dbCacheSize = 500;
    private static Thread saverdbThread;

    public OperationLogSaver() {
        init();
    }

    public void putRecord(List<TSysUpdateLog> records){
        queue.addAll(records);
    }

    public void putRecord(TSysUpdateLog record){
        try {
            queue.put(record);
        } catch (InterruptedException e) {
            logger.error(e.getMessage(),e);
        }
    }

    public void init() {
        queue = new LinkedBlockingQueue<TSysUpdateLog>();

        saverdbThread = new Thread("operationLog-Saver") {
            @Override
            public void run() {
                try {
                    while (true) {
                        if(null == queue || queue.isEmpty()){
                            Thread.sleep(500);
                            continue;
                        }
                        List<TSysUpdateLog> list = new ArrayList<TSysUpdateLog>();
                        queue.drainTo(list, dbCacheSize);
                        if(null != list && list.size() > 0){
//                            tSysUpdateLogMapper.batchInsert(list);
                            daoUtil.batchInsert("tk.mybatis.mapper.dao.TSysUpdateLogMapper","insertSelective",list);
                            Thread.sleep(1000);
                        }
                    }
                } catch (Exception t) {
                    logger.error("Unexpected exception on Thread %s!", t);
                }
            }
        };
        saverdbThread.start();
    }
}

借用 mybatis 向数据库批量插入操作记录
package com.dp.common.dao;

import java.util.List;

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository("daoUtil")
public class DaoUtil {
	protected final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    public final <O> boolean batchInsert(String sqlMapNameSpace,String statementName, final List<O> list) {
        boolean rt = true;
        // 此代码没有使用spring的事务,改动手动控制,如果和原spring事务一起使用,将无法回滚,必须注意,最好单独使用;
        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        int size = list.size();
        try {
            for (int i = 0; i < size; i++) {
                O paramObj = list.get(i);
                sqlSession.insert(sqlMapNameSpace + "." + statementName, paramObj);
                if ((i + 1) % 200 == 0 || (i + 1) == (size)) {
                    // 手动每200条提交一次,提交后无法回滚
                    sqlSession.commit();
                    // 清理缓存,防止溢出
                    sqlSession.clearCache();
                }
            }
        } catch (Exception e) {
            // 没有提交的数据可以回滚
            sqlSession.rollback();
            logger.error(e.getMessage(),e);
            rt = false;
        } finally {
            sqlSession.close();
        }
        return rt;
    }
}

在正常业务程序中这样使用异步写日志的工具类
@Autowired
private OperationLogSaver operationLogSaver;

// 保存操作记录
List<TSysUpdateLog> records = new ArrayList<>();

// 异步写日志
operationLogSaver.putRecord(records);

猜你喜欢

转载自blog.csdn.net/DaleyZou/article/details/85339362
今日推荐