Skip to main content

并发控制

系统的并发控制通过加锁来实现,锁分乐观锁和悲观锁两种。乐观锁是事后补救措施,通过管理数据版本来实现;悲观锁是事前预防措施,通过数据库的锁机制来实现.

问题描述#

场景一#

某大型企业内有一个 Helpdesk 小组通过系统来回答员工的各种问题。A 打开一个问题进行回答,B 同时也打开了同一个问题进行回答。 A 先完成并且提交,B 后完成提交的时候就会出现把 A 的回答内容覆盖的情况。问题的出现是由于两个用户对同一条数据进行并发访问造成的。

场景二#

乐观锁(Optimistic Locking)#

乐观锁(optimistic locking) 适合对同一条数据进行并发访问发生率低的业务场景,通过对数据版本的控制来解决冲突。具体的解决策略有 3 种:

  • 先更新为最终数据
  • 后更新为最终数据
  • 根据数据更新具体情况进行合并(merge)
解决方法#

在数据实体中加入一个 version 属性,在读取数据时连同版本号一同读取,更新时比对之前读取的版本号和数据中的版本号。如果版本号一致就更新,否则:(策略不同而不同)

  • 先更新为最终数据:返回错误。
  • 后更新为最终数据:overwrite = true,强制更新。
  • 根据数据更新具体情况进行合并(merge):更具一组逻辑合并数据更新。
student
{
"id" : 1,
"name" : "王强",
"birthday" : "1986-09-01",
"verison" : 4
}
{
"error": {
"name": "STALE_DATA_STATE",
"message": "数据更新冲突,数据状态过于陈旧",
}
}

悲观锁(Pessimistic Locking)#

认证授权相关的错误只允许返回 401403。以下是常见的错误类型定义,如果不能满足业务需求可以在此基础上扩展细化。

这个例子不靠谱,不是实际业务场景

start transaction; //开始事务
//查询申请信息,加锁锁定数据
select status from request where id = 1 for update;
//其他数据库处理
....
//修改申请状态
update request set status = "closed" where id = 1;
commit; //4.提交事务