异步往数据库中插入每个用户的增删改操作日志
用工具类异步向数据库中插入用户的操作日志
工具类代码如下:
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);