离线并发模式

乐观离线锁

使用冲突检测与事务回滚来防止事务冲突

通过版本号来实现

sequenceDiagram
  session1 ->> 数据库: 获取用户1
  数据库 ->> session1: 返回用户1 版本号1
  session1 ->> session1: 修改用户1
  session2 ->> 数据库: 获取用户1
  数据库 ->> session2: 返回用户1 版本号1
  session2 ->> session2: 修改用户1
  session2 ->> 数据库: 提交 用户1 版本号 1
  数据库 ->> session2: 修改用户1成功 版本号2
  session1 ->> 数据库: 提交 用户1 版本号 1
  数据库 -->> session1: 失败 版本号不一致
UPDATE users WHERE id = 1 AND version = 1;

这种乐观的离线锁是针对具体领域的解决方案

悲观离线锁

每次只允许一个会话访问数据

sequenceDiagram
  par 事务边界
    session1 ->> 数据库: 获取用户1
    数据库 ->> session1: 返回用户1
  end
  par 事务边界
    session2 ->> 数据库: 获取用户1
    数据库 -->> session2: 失败 用户1被锁住
  end
  session1 ->> session1: 修改用户1

尽可能早检测出冲突

锁的类型:

锁管理对象

如何管理锁与锁的持有者?

实现尽可能简单,使用散列表映射锁及锁的持有者

粗粒度锁

用锁锁住一组相关的对象,DDD中的聚合根就可以代表是锁的入口点

隐含锁

将加锁的任务交给父类或者框架,避免繁琐的客户编程加锁释放锁导致出现的问题