You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JMeter中实现无冲突的数据删除?

解决并行线程组POST/GET/DELETE数据库操作冲突的方案

针对你遇到的并行线程组操作数据库时的查询-删除冲突问题,以下是几个不依赖同步定时器、能保障吞吐量的可行方案:

1. 软删除+延迟物理删除

  • 给数据表新增一个status字段(比如VARCHAR(20),可选值active/deleted),默认值为active
  • DELETE线程组不直接执行物理删除,而是执行状态更新:
    UPDATE table SET status = 'deleted' WHERE id = ?
    
  • GET线程组只查询状态为活跃的数据:
    SELECT * FROM table WHERE status = 'active' AND [你的其他查询条件]
    
  • 新增独立的定时清理线程组(比如每10分钟执行一次),批量删除标记为deleted且超过阈值时长的记录:
    DELETE FROM table WHERE status = 'deleted' AND create_time < DATE_SUB(NOW(), INTERVAL 10 MINUTE)
    
    核心线程组的操作完全无锁无阻塞,清理操作后台异步执行,不会影响主流程吞吐量。

2. 数据分片隔离

  • 按时间或批次对数据做逻辑分片,新增shard_key字段(比如按小时生成,格式YYYYMMDDHH)
  • POST线程组写入数据时,自动填充当前时间对应的shard_key
  • GET线程组仅查询当前和最近N个分片的数据(比如当前小时+上一小时的分片)
  • DELETE线程组只删除早于N+1个分片的数据(比如删除两小时前的分片)
  • 示例:
    • POST写入:INSERT INTO table (shard_key, ...) VALUES ('2024052014', ...)
    • GET查询:SELECT * FROM table WHERE shard_key IN ('2024052014', '2024052013') AND [你的其他条件]
    • DELETE删除:DELETE FROM table WHERE shard_key < '2024052012'
      三个线程组操作完全不重叠的数据集合,从根源避免冲突,批量操作也能保障吞吐量。

3. 基于队列的生产消费解耦

  • 利用Redis内存队列实现数据ID的分发:
    • POST线程组新增数据后,将记录ID推入Redis的active_data列表(用LPUSH)
    • GET线程组从列表左侧取ID查询(LPOP或BLPOP,设置短超时)
    • DELETE线程组从列表右侧取ID删除(RPOP或BRPOP)
  • 队列操作是原子性的,确保同一个ID不会同时被GET和DELETE处理,三个线程组操作完全解耦,数据库层面无交叉操作,吞吐量最大化。
  • 可根据业务调整:比如GET查询完成后再将ID移到删除队列,确保数据被查询后再删除。

4. 数据库行级锁+重试机制

  • 如果必须物理删除,在DELETE操作前加行级锁,避免GET读取待删除记录:
    • DELETE线程组先执行锁查询,跳过已锁定的记录避免阻塞:
      SELECT id FROM table WHERE [删除条件] FOR UPDATE SKIP LOCKED
      
      拿到ID后再执行DELETE操作
    • GET线程组添加重试控制器(设置1-2次短超时重试),将"记录不存在"的单次失败转为可恢复的场景
      行级锁粒度小,不会影响其他记录操作,吞吐量损失极小。

额外优化建议

  • 调整GET请求的断言逻辑,将"记录不存在"的情况标记为非错误(比如返回空结果时视为成功),避免这类场景被统计为失败请求
  • 平衡三个线程组的并发数比例,比如让POST并发数略高于GET和DELETE,确保有足够的活跃数据供GET查询

内容的提问来源于stack exchange,提问作者Singularity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:46:13