状态标志(业务锁)实现方案

嚴華  论坛元老 | 2025-4-28 10:18:36 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1855|帖子 1855|积分 5565

票据数据污染解决方案-状态标志(业务锁)

票据数据污染解决方案-状态标志(业务锁)
感觉本篇对你有帮助可以关注一下我的微信公众号(深入浅出谈java),会不定期更新知识和口试资料、本领!!!

如何防止票据数据被多人操作,造成数据污染?
确保同一时间只有一个用户可以编辑票据,或者至少能检测到并发修改,避免数据辩论。比如当用户尝试编辑一个被锁定的票据时,提示“当前票据正被其他用户编辑”。同时,在服务端处理并发请求时,确保更新状态的原子性,避免竞态条件。
这时候,我应该考虑常见的并发控制方法。比如乐观锁和灰心锁,这两种方法在开辟中常常用到。
本文主要针对的是 状态标志(业务锁)
解决方案

常见的解决方案包括:

  • 乐观锁:通过版本号或时间戳检测辩论。
  • 灰心锁:在事务中使用行级锁。
  • 状态标志:联合超时机制防止死锁。
  • 前端提示和实时检测。
  • 操作日记和版本比对。
  • 分布式锁应对多实例情况。
  • 权限控制淘汰辩论大概性。
需要根据具体场景选择合适的方案,或者组合使用多种方法。比方,使用乐观锁处理大部分情况,联合前端提示和状态标志来提升用户体验。或者在高并发场景下使用灰心锁,同时设置合理的超时时间。
其他解决办法可阅读:票据污染解决方案 - 古渡蓝按 - 博客园
流程图


核心逻辑

状态标志。在票据表中增加一个状态字段,比如“编辑中”,当用户开始编辑时,将状态设为不可编辑,保存后再规复。这种方法需要前端和后端配合,比如用户点击编辑时,后端检查状态是否为可编辑,假如是,就设为编辑中,防止其他人编辑。但大概存在用户忘记保存或者非常退出的情况,导致状态不停处于编辑中,所以大概需要一个超时机制,自动释放状态。
状态标志(业务锁)核心逻辑

通过业务字段标志票据的编辑状态,确保同一时间只有一个用户能操作票据。
关键点

  • 使用数据库字段(如 status)标志票据是否被锁定。
  • 用户尝试编辑时,检查并抢占锁;编辑完成后释放锁。
  • 超时机制:防止用户未提交导致锁永久占用。
具体实现步调

1. 数据库设计

比方:在票据表中添加字段
字段名范例分析statusint0-可编辑,1-编辑中lock_byvarchar锁定者(用户ID)lock_timedatetime锁定时间(用于超时释放)2. 用户操作流程

步调用户行为前端服务端逻辑数据库操作1用户A点击“编辑”按钮发送/lock请求,携带票据ID检查当前票据状态: 若status=0,更新为status=1,记录lock_by和lock_timeUPDATE table SET status=1, lock_by='A', lock_time=NOW() WHERE id=123 AND status=02用户A编辑表单表单展示,禁用其他用户操作入口保持锁定状态无3用户A提交保存发送保存请求,携带修改数据更新票据数据,并释放锁(status=0)UPDATE table SET ..., status=0 WHERE id=123 AND lock_by='A'4用户B尝试编辑同一票据发送/lock请求检查状态:status=1,返回“票据已超时释放锁


  • 后台定时使命:每隔N分钟扫描lock_time超时的票据,自动释放锁:
    1. UPDATE table SET status=0
    2. WHERE status=1 AND lock_time < NOW() - INTERVAL '5 MINUTE';
    复制代码
伪代码

1. 服务端锁定逻辑(伪代码)
  1. def lock_order(order_id, user_id):
  2.     # 原子操作:尝试锁定
  3.     updated = execute_sql(
  4.         "UPDATE orders SET status=1, lock_by=%s, lock_time=NOW() "
  5.         "WHERE id=%s AND status=0",
  6.         [user_id, order_id]
  7.     )
  8.     if updated == 0:
  9.         # 获取当前锁定者信息
  10.         locked_by = execute_sql(
  11.             "SELECT lock_by FROM orders WHERE id=%s", [order_id]
  12.         )
  13.         return {"success": False, "message": f"单据已被{locked_by}占用"}
  14.     return {"success": True}
复制代码
2. 前端提示逻辑(伪代码)
  1. // 用户点击编辑按钮
  2. async function handleEdit(orderId) {
  3.   const res = await fetch('/lock', { method: 'POST', body: { orderId } });
  4.   if (!res.success) {
  5.     alert(res.message); // 如“单据已被张三锁定”
  6.   } else {
  7.     // 进入编辑模式
  8.   }
  9. }
复制代码
注意事项


  • 原子性:锁定操作需通过单条SQL包管原子性(避免竞态条件)。
  • 锁释放

    • 用户提交后必须释放锁。
    • 非常场景(如用户关闭页面)依赖后台超时释放。

  • 用户体验

    • 前端可轮询检查锁状态(如每30秒查询一次)。
    • 提示具体锁定者(如“票据正被张三编辑”)。

通过状态标志机制,可低成本实现多人操作辩论控制,适合中小型系统或业务流程明确的场景。
最后文章有啥不对,欢迎大佬在评论区指点!!!
假如感觉对你有帮助就点赞推荐或者关注一下吧!!!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表