本文主要研究一下nacos config的deleteConfig
nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java
@Controller @RequestMapping(Constants.CONFIG_CONTROLLER_PATH) public class ConfigController { private static final Logger log = LoggerFactory.getLogger(ConfigController.class); private static final String NAMESPACE_PUBLIC_KEY = "public"; public static final String EXPORT_CONFIG_FILE_NAME = "nacos_config_export_"; public static final String EXPORT_CONFIG_FILE_NAME_EXT = ".zip"; public static final String EXPORT_CONFIG_FILE_NAME_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private final transient ConfigServletInner inner; private final transient PersistService persistService; private final transient ConfigSubService configSubService; //...... /** * 同步删除某个dataId下面所有的聚合前数据 * * @throws NacosException */ @RequestMapping(method = RequestMethod.DELETE) @ResponseBody public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response, @RequestParam("dataId") String dataId, // @RequestParam("group") String group, // @RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant, @RequestParam(value = "tag", required = false) String tag) throws NacosException { ParamUtils.checkParam(dataId, group, "datumId", "rm"); ParamUtils.checkParam(tag); String clientIp = RequestUtil.getRemoteIp(request); if (StringUtils.isBlank(tag)) { persistService.removeConfigInfo(dataId, group, tenant, clientIp, null); } else { persistService.removeConfigInfoTag(dataId, group, tenant, tag, clientIp, null); } final Timestamp time = TimeUtils.getCurrentTime(); ConfigTraceService.logPersistenceEvent(dataId, group, tenant, null, time.getTime(), clientIp, ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null); EventDispatcher.fireEvent(new ConfigDataChangeEvent(false, dataId, group, tenant, tag, time.getTime())); return true; } /** * @author klw * @Description: delete configuration based on multiple config ids * @Date 2019/7/5 10:26 * @Param [request, response, dataId, group, tenant, tag] * @return java.lang.Boolean */ @RequestMapping(params = "delType=ids", method = RequestMethod.DELETE) @ResponseBody public RestResult<Boolean> deleteConfigs(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "ids")List<Long> ids) { String clientIp = RequestUtil.getRemoteIp(request); final Timestamp time = TimeUtils.getCurrentTime(); List<ConfigInfo> configInfoList = persistService.removeConfigInfoByIds(ids, clientIp, null); if(!CollectionUtils.isEmpty(configInfoList)){ for(ConfigInfo configInfo : configInfoList) { ConfigTraceService.logPersistenceEvent(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), null, time.getTime(), clientIp, ConfigTraceService.PERSISTENCE_EVENT_REMOVE, null); EventDispatcher.fireEvent(new ConfigDataChangeEvent(false, configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), time.getTime())); } } return ResultBuilder.buildSuccessResult(true); } //...... }
nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/service/PersistService.java
@Repository public class PersistService { @Autowired private DynamicDataSource dynamicDataSource; private DataSourceService dataSourceService; private static final String SQL_FIND_ALL_CONFIG_INFO = "select data_id,group_id,tenant_id,app_name,content,type from config_info"; private static final String SQL_TENANT_INFO_COUNT_BY_TENANT_ID = "select count(1) from tenant_info where tenant_id = ?"; private static final String SQL_FIND_CONFIG_INFO_BY_IDS = "SELECT ID,data_id,group_id,tenant_id,app_name,content,md5 FROM config_info WHERE "; private static final String SQL_DELETE_CONFIG_INFO_BY_IDS = "DELETE FROM config_info WHERE "; /** * @author klw * @Description: constant variables */ public static final String SPOT = "."; @PostConstruct public void init() { dataSourceService = dynamicDataSource.getDataSource(); jt = getJdbcTemplate(); tjt = getTransactionTemplate(); } //...... /** * 删除配置信息, 物理删除 */ public void removeConfigInfo(final String dataId, final String group, final String tenant, final String srcIp, final String srcUser) { tjt.execute(new TransactionCallback<Boolean>() { final Timestamp time = new Timestamp(System.currentTimeMillis()); @Override public Boolean doInTransaction(TransactionStatus status) { try { ConfigInfo configInfo = findConfigInfo(dataId, group, tenant); if (configInfo != null) { removeConfigInfoAtomic(dataId, group, tenant, srcIp, srcUser); removeTagByIdAtomic(configInfo.getId()); insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, srcUser, time, "D"); } } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } return Boolean.TRUE; } }); } /** * 删除配置;数据库原子操作,最小sql动作,无业务封装 * * @param dataId dataId * @param group group * @param tenant tenant * @param tag tag * @param srcIp ip * @param srcUser user */ public void removeConfigInfoTag(final String dataId, final String group, final String tenant, final String tag, final String srcIp, final String srcUser) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; String tagTmp = StringUtils.isBlank(tag) ? StringUtils.EMPTY : tag; try { jt.update("DELETE FROM config_info_tag WHERE data_id=? AND group_id=? AND tenant_id=? AND tag_id=?", dataId, group, tenantTmp, tagTmp); } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } /** * @author klw * @Description: delete config info by ids * @Date 2019/7/5 16:45 * @Param [ids, srcIp, srcUser] * @return List<ConfigInfo> deleted configInfos */ public List<ConfigInfo> removeConfigInfoByIds(final List<Long> ids, final String srcIp, final String srcUser) { if(CollectionUtils.isEmpty(ids)){ return null; } ids.removeAll(Collections.singleton(null)); return tjt.execute(new TransactionCallback<List<ConfigInfo>>() { final Timestamp time = new Timestamp(System.currentTimeMillis()); @Override public List<ConfigInfo> doInTransaction(TransactionStatus status) { try { String idsStr = Joiner.on(",").join(ids); List<ConfigInfo> configInfoList = findConfigInfosByIds(idsStr); if (!CollectionUtils.isEmpty(configInfoList)) { removeConfigInfoByIdsAtomic(idsStr); for(ConfigInfo configInfo : configInfoList){ removeTagByIdAtomic(configInfo.getId()); insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, srcUser, time, "D"); } } return configInfoList; } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } }); } /** * 删除配置;数据库原子操作,最小sql动作,无业务封装 * * @param dataId dataId * @param group group * @param tenant tenant * @param srcIp ip * @param srcUser user */ private void removeConfigInfoAtomic(final String dataId, final String group, final String tenant, final String srcIp, final String srcUser) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; try { jt.update("DELETE FROM config_info WHERE data_id=? AND group_id=? AND tenant_id=?", dataId, group, tenantTmp); } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } public void removeTagByIdAtomic(long id) { try { jt.update("DELETE FROM config_tags_relation WHERE id=?", id); } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } /** * 更新变更记录;数据库原子操作,最小sql动作,无业务封装 * * @param id id * @param configInfo config info * @param srcIp ip * @param srcUser user * @param time time * @param ops ops type */ private void insertConfigHistoryAtomic(long id, ConfigInfo configInfo, String srcIp, String srcUser, final Timestamp time, String ops) { String appNameTmp = StringUtils.isBlank(configInfo.getAppName()) ? StringUtils.EMPTY : configInfo.getAppName(); String tenantTmp = StringUtils.isBlank(configInfo.getTenant()) ? StringUtils.EMPTY : configInfo.getTenant(); final String md5Tmp = MD5.getInstance().getMD5String(configInfo.getContent()); try { jt.update( "INSERT INTO his_config_info (id,data_id,group_id,tenant_id,app_name,content,md5,src_ip,src_user,gmt_modified,op_type) VALUES(?,?,?,?,?,?,?,?,?,?,?)", id, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, appNameTmp, configInfo.getContent(), md5Tmp, srcIp, srcUser, time, ops); } catch (DataAccessException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } /** * @author klw * @Description: find ConfigInfo by ids * @Date 2019/7/5 16:37 * @Param [ids] * @return java.util.List<com.alibaba.nacos.config.server.model.ConfigInfo> */ public List<ConfigInfo> findConfigInfosByIds(final String ids) { if(StringUtils.isBlank(ids)){ return null; } StringBuilder sql = new StringBuilder(SQL_FIND_CONFIG_INFO_BY_IDS); sql.append("id in ("); List<Long> paramList = new ArrayList<>(); String[] tagArr = ids.split(","); for (int i = 0; i < tagArr.length; i++) { if (i != 0) { sql.append(", "); } sql.append("?"); paramList.add(Long.valueOf(tagArr[i])); } sql.append(") "); try { return this.jt.query(sql.toString(), paramList.toArray(), CONFIG_INFO_ROW_MAPPER); } catch (EmptyResultDataAccessException e) { // 表明数据不存在, 返回null return null; } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } /** * @author klw * @Description: Delete configuration; database atomic operation, minimum SQL action, no business encapsulation * @Date 2019/7/5 16:39 * @Param [id] * @return void */ private void removeConfigInfoByIdsAtomic(final String ids) { if(StringUtils.isBlank(ids)){ return; } StringBuilder sql = new StringBuilder(SQL_DELETE_CONFIG_INFO_BY_IDS); sql.append("id in ("); List<Long> paramList = new ArrayList<>(); String[] tagArr = ids.split(","); for (int i = 0; i < tagArr.length; i++) { if (i != 0) { sql.append(", "); } sql.append("?"); paramList.add(Long.valueOf(tagArr[i])); } sql.append(") "); try { jt.update(sql.toString(), paramList.toArray()); } catch (CannotGetJdbcConnectionException e) { fatalLog.error("[db-error] " + e.toString(), e); throw e; } } //...... }
ConfigController的deleteConfig方法主要是调用persistService.removeConfigInfo或者persistService.removeConfigInfoTag;deleteConfigs方法主要是调用persistService.removeConfigInfoByIds