異步往數據庫中插入每個用戶的增刪改操作日志


  • [x] 我們需要一個工具類

用工具類異步向數據庫中插入用戶的操作日志

工具類代碼如下:
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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM