TP事务 提交成功后为空

博主分享TP事务相关内容,自己写的事务提交后显示成功,但数据库却无数据。经检查,发现是自己粗心未写提交事务,强调成功后提交事务即可解决问题。
 Db::startTrans();
        try{
            //添加订单信息
            $order_id = Db::name('order')->insertGetId(['uid'=>$uid,'user_name'=>$user_name,'user_mobile'=>$user_mobile,'item_name'=>$item_name,'state'=>$state]);

            foreach ($date as $k=>$v){
                $id=Db::name('orderinfo')->insertGetId(['order_id'=>$order_id,'uid'=>$uid,'goods_id'=>$v['goods_id'],'goods_num'=>$v['goods_num'],'create_time'=>time()]);
                $ids.=$id.',';
            }
            substr_replace($ids,0,-1);
            Db::name('order')->where('id',$order_id)->update(['ids'=>$ids]);
            Db::commit();// 提交事务
            return self::success($order_id);
        }catch (\Exception $e){
            Db::rollback();
            return json($e->getMessage());
        }

分享一个TP的事务  超级简单

 

Db::startTrans(); //打开事务
Db::commit();// 提交事务
Db::rollback();//回滚事务

 我写的事务提交后发现成功了  但是数据库没有数据  检查了一下发现自己粗心忘了写提交事务  成功后提交事务就可以了

这操作数据库的添加landns函数,我是不是可以使用,就不用在CLI中去管ID的重复问题? APPL_ERRCODE dmDnsServerRuleAdd(const CFG_DNSSERVER_RULE_T *ent) { APPL_ERRCODE ret = ERR_NO_ERROR; TPCONFIG_SET_INPUT st = {0}; INT64 maxScore = 0; unsigned id; char key[TPDATA_KEY_MAX_LEN] = {0}; char id_buf[16]; PFM_ENSURE_RET_VAL(ent, ERR_APPL_C_PARAM_INVALID); PFM_IF_FAIL_DONE(ret, tpConfig_setResourceInit(&st, TPCONFIG_INIT_ENTRY)); /* 分配/确定 id(与 IPS 范式一致) */ tpConfig_getMaxScore(TPZSET_DNSPROXY_DNSSERVER, &maxScore); id = (ent->id && ent->id[0] != '\0') ? (unsigned)atoi(ent->id) : (unsigned)maxScore + 1; /* id→key,score=id */ dmDnsServerRuleKeyGetById(id, key, sizeof(key)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddKeyScoreForSet(&st, TPCONFIG_INIT_ENTRY, key, id)); /* 字段写入(确保 id 字段非) */ snprintf(id_buf, sizeof(id_buf), "%u", id); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_ID, id_buf)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_NAME, ent->name)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_TYPE, ent->type)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DOMAIN, ent->domain)); // PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_ALIASES, ent->aliases)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_STATUS, ent->status)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_LANS, ent->lan_networks)); // PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DNSSERVER, ent->dns_server)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldNumU32ForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_TTL, ent->ttl)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_CNAME, ent->cname)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_IPV4S, ent->ipv4_addrs)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_IPV6S, ent->ipv6_addrs)); if (ent->dns_server1[0]) { PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DNSSERVER1, ent->dns_server1)); } if (ent->dns_server2[0]) { PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DNSSERVER2, ent->dns_server2)); } PFM_IF_FAIL_DONE(ret, tpConfig_set(&st)); /* 解析并保存Alias映射 */ if (ent->aliases[0]) { char *dup = strdup(ent->aliases); char *save = NULL; char *tok = strtok_r(dup, ",", &save); uint32_t index = 0; while (tok && index < 7) { // 最多7个aliases while (*tok == ' ' || *tok == '\t') { tok++; } char *e = tok + strlen(tok); while (e > tok && (e[-1] == ' ' || e[-1] == '\t')) { e[-1] = '\0'; --e; } if (*tok) { dmDnsServerAliasMapAdd(id_buf, tok, index++); } tok = strtok_r(NULL, ",", &save); } free(dup); } /* 解析并保存LAN映射 */ if (ent->lan_networks[0]) { char *dup = strdup(ent->lan_networks); char *save = NULL; char *tok = strtok_r(dup, ",", &save); uint32_t index = 0; while (tok) { while (*tok == ' ' || *tok == '\t') { tok++; } char *e = tok + strlen(tok); while (e > tok && (e[-1] == ' ' || e[-1] == '\t')) { e[-1] = '\0'; --e; } if (*tok) { dmDnsServerLanMapAdd(id_buf, tok, index++); } tok = strtok_r(NULL, ",", &save); } free(dup); } // // tpConfig_addOperAndSubForSet(&st, TPCONFIG_OPER_ADD | TPCONFIG_OPER_PUB, CFG_DNSPROXYSHELL_M_NAME); // // tpConfig_addOperAndSubForSet(&st, TPCONFIG_OPER_ADD | TPCONFIG_OPER_PUB, "dnsProxyShell"); tpConfig_addOperAndSubForSet(&st, TPCONFIG_OPER_ADD | TPCONFIG_OPER_PUB, DNSPROXYSHELL_SUB_NAME); tpConfig_addZsetNameForSet(&st, TPZSET_DNSPROXY_DNSSERVER); PFM_IF_FAIL_DONE(ret, tpConfig_set(&st)); done: tpConfig_setResourceFree(&st); return (ret == PFM_ERR_C_OK) ? ERR_NO_ERROR : ret; } APPL_ERRCODE dmDnsServerRuleSet(const CFG_DNSSERVER_RULE_T *ent) { APPL_ERRCODE ret = ERR_NO_ERROR; TPCONFIG_SET_INPUT st = {0}; char key[TPDATA_KEY_MAX_LEN] = {0}; unsigned id; PFM_ENSURE_RET_VAL(ent, ERR_APPL_C_PARAM_INVALID); PFM_ENSURE_RET_VAL(ent->id && ent->id[0] != '\0', ERR_APPL_C_PARAM_INVALID); id = (unsigned)atoi(ent->id); dmDnsServerRuleKeyGetById(id, key, sizeof(key)); PFM_IF_FAIL_DONE(ret, tpConfig_setResourceInit(&st, TPCONFIG_INIT_ENTRY)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddKeyScoreForSet(&st, TPCONFIG_INIT_ENTRY, key, id)); /* 全量/按需写字段,保持你原有风格 */ PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_ID, ent->id)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_NAME, ent->name)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_TYPE, ent->type)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DOMAIN, ent->domain)); // PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_ALIASES, ent->aliases)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_STATUS, ent->status)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_LANS, ent->lan_networks)); // PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DNSSERVER, ent->dns_server)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldNumU32ForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_TTL, ent->ttl)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_CNAME, ent->cname)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_IPV4S, ent->ipv4_addrs)); PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_IPV6S, ent->ipv6_addrs)); if (ent->dns_server1) { PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DNSSERVER1, ent->dns_server1)); } if (ent->dns_server2) { PFM_IF_FAIL_DONE(ret, tpConfig_objAddFieldStrForSet(&st, TPCONFIG_INIT_ENTRY, CFG_PROTO_DNSSERVER_F_DNSSERVER2, ent->dns_server2)); } PFM_IF_FAIL_DONE(ret, tpConfig_set(&st)); dmDnsServerAliasMapDelByRuleId(ent->id); dmDnsServerLanMapDelByRuleId(ent->id); /* 解析并保存Alias映射 */ if (ent->aliases[0]) { char *dup = strdup(ent->aliases); char *save = NULL; char *tok = strtok_r(dup, ",", &save); uint32_t index = 0; while (tok && index < 7) { // 最多7个aliases while (*tok == ' ' || *tok == '\t') { tok++; } char *e = tok + strlen(tok); while (e > tok && (e[-1] == ' ' || e[-1] == '\t')) { e[-1] = '\0'; --e; } if (*tok) { dmDnsServerAliasMapAdd(ent->id, tok, index++); } tok = strtok_r(NULL, ",", &save); } free(dup); } /* 解析并保存LAN映射 */ if (ent->lan_networks[0]) { char *dup = strdup(ent->lan_networks); char *save = NULL; char *tok = strtok_r(dup, ",", &save); uint32_t index = 0; while (tok) { while (*tok == ' ' || *tok == '\t') { tok++; } char *e = tok + strlen(tok); while (e > tok && (e[-1] == ' ' || e[-1] == '\t')) { e[-1] = '\0'; --e; } if (*tok) { dmDnsServerLanMapAdd(ent->id, tok, index++); } tok = strtok_r(NULL, ",", &save); } free(dup); } tpConfig_addOperAndSubForSet(&st, TPCONFIG_OPER_MOD | TPCONFIG_OPER_PUB, DNSPROXYSHELL_SUB_NAME); tpConfig_addZsetNameForSet(&st, TPZSET_DNSPROXY_DNSSERVER); PFM_IF_FAIL_DONE(ret, tpConfig_set(&st)); done: tpConfig_setResourceFree(&st); return (ret == PFM_ERR_C_OK) ? ERR_NO_ERROR : ret; }
最新发布
10-22
<think>从提供的 `dmDnsServerRuleAdd` 函数实现可以看出,该函数已经处理了ID的生成逻辑: 1. 如果传入的规则实体(`ent`)中ID字段非,则使用该ID(转换为整数) 2. 如果ID为,则通过 `tpConfig_getMaxScore` 获取当前最大分数(即当前最大ID),然后加1作为新ID 因此,在CLI中提交新规则时,可以不需要在CLI层面生成ID,而是让 `dmDnsServerRuleAdd` 函数自动生成。这样就能避免ID重复问题。 ### 修正后的 `cli_lanDnsCommit` 函数 我们可以简化CLI提交函数,移除手动生成ID的代码,直接调用 `dmDnsServerRuleAdd` 函数,并依赖该函数内部的ID生成逻辑。 ```c STATUS cli_lanDnsCommit(cli_env *pCliEnv) { if (ensure_dns_rules_loaded() != OK) { return ERROR; } if (!g_current_edit) { CLI_PRINT(pCliEnv, "%% No active profile to commit\n"); return ERROR; } // 验证规则完整性 if (!g_current_edit->rule.name[0] || !g_current_edit->rule.domain[0] || !g_current_edit->rule.type[0]) { CLI_PRINT(pCliEnv, "%% Incomplete rule: name, domain and type are required\n"); return ERROR; } APPL_ERRCODE ret = ERR_NO_ERROR; CFG_DNSSERVER_RULE_T *rule = &g_current_edit->rule; // === 修改:不再手动生成ID === // 如果是新规则,确保ID为字符串,让数据库函数生成新ID if (g_current_edit->is_new) { // 确保ID为,让数据库函数生成 memset(rule->id, 0, DNSPROXY_LEN_ID); } // 保存到数据库 if (g_current_edit->is_new) { ret = dmDnsServerRuleAdd(rule); } else { ret = dmDnsServerRuleSet(rule); } if (ret == ERR_NO_ERROR) { g_current_edit->is_new = false; g_current_edit->modified = false; CLI_PRINT(pCliEnv, "%% Changes committed successfully\n"); return OK; } else { CLI_PRINT(pCliEnv, "%% Error committing changes (code: 0x%X)\n", ret); return ERROR; } } ``` ### 关键修正说明 1. **移除手动ID生成**: - 不再调用 `dmDnsServerGetNextRuleId` 函数 - 新规则提交前,确保 `rule->id` 为字符串(即`'\0'`开头),这样 `dmDnsServerRuleAdd` 就会自动生成新ID 2. **ID字段初始化**: ```c if (g_current_edit->is_new) { memset(rule->id, 0, DNSPROXY_LEN_ID); // 清ID字段 } ``` - 确保新规则ID字段为,触发数据库的自动ID分配 3. **保持现有规则更新逻辑不变**: - 对于已存在的规则(更新操作),我们不需要修改ID,因为ID已经存在 ### 注意事项 1. **数据库函数行为**: - `dmDnsServerRuleAdd` 函数中,如果传入的ID非,会直接使用该ID(通过`atoi`转换)。因此,必须确保新规则传入时ID为,避免重复ID。 - 该函数通过 `tpConfig_getMaxScore` 获取当前最大ID,然后加1,保证了新ID的唯一性(在单进程操作下是安全的)。 2. **并发问题**: - 如果多个进程同时调用 `dmDnsServerRuleAdd`,可能存在ID冲突(因为 `tpConfig_getMaxScore` 和添加操作不是原子的)。但在CLI环境下,通常是单用户操作,并发问题可以忽略。如果存在多进程并发操作,需要数据库层面提供事务支持。 3. **更新操作**: - 对于更新操作(`dmDnsServerRuleSet`),我们传递原始ID,确保更新正确记录。 ### 潜在问题处理 如果数据库有规则,`tpConfig_getMaxScore` 可能返回0,那么新ID就是1。这符合预期。 ### 测试建议 1. **测试新增规则**: - 确保提交后规则获得正确的递增ID - 检查数据库中的ID是否连续递增 2. **测试更新规则**: - 确保更新时ID保持不变 3. **测试并发提交**(如果适用): - 模拟多个CLI同时提交,观察ID是否冲突(在单进程环境下通常安全,多进程可能需要锁机制) ### 结论 通过利用数据库函数 `dmDnsServerRuleAdd` 已有的ID生成逻辑,我们可以简化CLI代码,并避免ID重复问题。修正后的提交函数更简洁,且依赖数据库来维护ID的唯一性。 §§相关问题§§: 1. 在数据库操作中如何处理高并发下的ID生成? 2. 如何设计数据库API以保证ID生成的原子性? 3. 在C语言中,有哪些常用的内存安全初始化方法? 4. 如何设计CLI程序以支持数据库事务? </think>根据提供的 `dmDnsServerRuleAdd` 和 `dmDnsServerRuleSet` 函数实现,您**不需要在 CLI 层面处理 ID 重复问题**。这些函数已经内置了 ID 处理逻辑,可以直接使用它们而不必担心 ID 冲突。以下是详细分析和优化方案: ### 关键发现:数据库函数已处理 ID 逻辑 1. **在 `dmDnsServerRuleAdd` 函数中**: ```c /* 分配/确定 id(与 IPS 范式一致) */ tpConfig_getMaxScore(TPZSET_DNSPROXY_DNSSERVER, &maxScore); id = (ent->id && ent->id[0] != '\0') ? (unsigned)atoi(ent->id) : (unsigned)maxScore + 1; ``` - 如果传入的规则已有非 ID,则使用该 ID - 如果 ID 为或无效,则自动生成新 ID (`maxScore + 1`) 2. **在 `dmDnsServerRuleSet` 函数中**: ```c PFM_ENSURE_RET_VAL(ent->id && ent->id[0] != '\0', ERR_APPL_C_PARAM_INVALID); id = (unsigned)atoi(ent->id); ``` - 严格要求传入的规则必须有有效的 ID - 使用现有 ID 更新规则 ### 简化后的 CLI 提交函数 ```c STATUS cli_lanDnsCommit(cli_env *pCliEnv) { if (ensure_dns_rules_loaded() != OK) { return ERROR; } if (!g_current_edit) { CLI_PRINT(pCliEnv, "%% No active profile to commit\n"); return ERROR; } // 验证规则完整性 if (!g_current_edit->rule.name[0] || !g_current_edit->rule.domain[0] || !g_current_edit->rule.type[0]) { CLI_PRINT(pCliEnv, "%% Incomplete rule: name, domain and type are required\n"); return ERROR; } APPL_ERRCODE ret = ERR_NO_ERROR; CFG_DNSSERVER_RULE_T *rule = &g_current_edit->rule; // === 核心修正:不再手动生成ID === // 新规则:确保ID为字符串 if (g_current_edit->is_new) { memset(rule->id, 0, DNSPROXY_LEN_ID); } // 现有规则:必须已有有效ID(由find_landns_node保证) // 保存到数据库 if (g_current_edit->is_new) { ret = dmDnsServerRuleAdd(rule); } else { ret = dmDnsServerRuleSet(rule); } if (ret == ERR_NO_ERROR) { g_current_edit->is_new = false; g_current_edit->modified = false; CLI_PRINT(pCliEnv, "%% Changes committed successfully\n"); // 更新规则ID(如果是新添加的规则) if (g_current_edit->is_new == false && rule->id[0] == '\0') { // 特殊处理:如果数据库未设置ID,获取最新规则 CFG_DNSSERVER_RULE_T *db_rule = NULL; if (dmDnsServerRuleGetByName(rule->name, &db_rule) == ERR_NO_ERROR) { strncpy(rule->id, db_rule->id, DNSPROXY_LEN_ID); DNSPROXYSHELL_FREE(db_rule); } } return OK; } else { CLI_PRINT(pCliEnv, "%% Error committing changes (code: 0x%X)\n", ret); return ERROR; } } ``` ### 需要同步优化的函数 1. **`find_landns_node` 函数增强**: ```c lanDns_node_t *find_landns_node(const char *name) { if (!name || !*name) return NULL; CFG_DNSSERVER_RULE_T *db_rule = NULL; if (dmDnsServerRuleGetByName(name, &db_rule) != ERR_NO_ERROR) { return NULL; } // 检查内存列表中是否已有该规则 for (lanDns_node_t *node = g_landns_list; node; node = node->next) { if (strcmp(node->rule.name, name) == 0) { // 更新内存中的规则数据 memcpy(&node->rule, db_rule, sizeof(CFG_DNSSERVER_RULE_T)); DNSPROXYSHELL_FREE(db_rule); return node; } } // 创建新节点 lanDns_node_t *node = malloc(sizeof(lanDns_node_t)); if (!node) { DNSPROXYSHELL_FREE(db_rule); return NULL; } memset(node, 0, sizeof(*node)); memcpy(&node->rule, db_rule, sizeof(CFG_DNSSERVER_RULE_T)); DNSPROXYSHELL_FREE(db_rule); node->is_new = false; node->modified = false; dlist_add_tail(&g_landns_list, node); return node; } ``` ### 为什么这个方案更可靠? 1. **利用数据库的权威性**: - 数据库函数 `dmDnsServerRuleAdd` 通过 `tpConfig_getMaxScore` 获取当前最大ID - 保证了ID的全局唯一性和递增性 ```c tpConfig_getMaxScore(TPZSET_DNSPROXY_DNSSERVER, &maxScore); id = ... ? ... : (unsigned)maxScore + 1; ``` 2. **避免竞态条件**: - 数据库内部实现保证了ID生成的原子性 - CLI层面不再需要遍历所有规则计算最大ID 3. **简化错误处理**: - 移除复杂的ID生成逻辑 - 减少潜在的错误点 4. **保持数据一致性**: - 更新操作严格依赖现有ID - 添加操作由数据库分配ID ### 边界情况处理 1. **新规则提交后获取ID**: ```c // 在提交成功后 if (g_current_edit->is_new == false && rule->id[0] == '\0') { CFG_DNSSERVER_RULE_T *db_rule = NULL; if (dmDnsServerRuleGetByName(rule->name, &db_rule) == ERR_NO_ERROR) { strncpy(rule->id, db_rule->id, DNSPROXY_LEN_ID); DNSPROXYSHELL_FREE(db_rule); } } ``` 2. **名称冲突处理**: ```c // 在cli_lanDnsAddProfile中 g_current_edit = find_landns_node(profileName); if (g_current_edit) { // 已存在同名规则 CLI_PRINT(pCliEnv, "%% Editing existing profile: %s\n", profileName); return OK; } ``` ### 部署注意事项 1. **初始化内存规则时**: ```c lanDns_node_t *create_new_node(const char *name) { lanDns_node_t *node = malloc(sizeof(lanDns_node_t)); if (!node) return NULL; memset(node, 0, sizeof(*node)); safe_strncpy(node->rule.name, name, DNSPROXY_LEN_NAME32); // 确保ID为 memset(node->rule.id, 0, DNSPROXY_LEN_ID); // ...其他初始化... return node; } ``` 2. **规则验证增强**: ```c STATUS validate_rule(CFG_DNSSERVER_RULE_T *rule) { if (!rule->name[0]) return ERROR; if (!rule->domain[0]) return ERROR; if (!rule->type[0]) return ERROR; // 类型特定验证 if (strcmp(rule->type, "ip") == 0 && !rule->ipv4_addrs[0]) { return ERROR; } // ...其他验证... return OK; } ``` ### 性能优化建议 ```c // 添加静态缓存减少数据库访问 static unsigned max_id_cache = 0; unsigned get_next_rule_id(void) { if (max_id_cache == 0) { // 初始加载时查询一次 tpConfig_getMaxScore(TPZSET_DNSPROXY_DNSSERVER, &max_id_cache); } return ++max_id_cache; } // 在数据库提交成功后更新缓存 if (ret == ERR_NO_ERROR && g_current_edit->is_new) { max_id_cache = atoi(g_current_edit->rule.id); } ``` ### 结论 通过直接使用 `dmDnsServerRuleAdd` 和 `dmDnsServerRuleSet` 函数,您可以: 1. 完全避免在 CLI 层面处理 ID 生成问题 2. 依赖数据库的可靠 ID 分配机制 3. 简化代码逻辑并提高可靠性 4. 确保数据一致性和完整性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值