異步往數據庫中插入每個用戶的增刪改操作日誌
阿新 • • 發佈:2018-12-29
run while empty sem 批量 異步 exp rri des
- [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);
異步往數據庫中插入每個用戶的增刪改操作日誌