mar*_*iva 13 domain-driven-design optimistic-concurrency event-sourcing
当您希望代码在竞争条件下工作时,通常开发人员使用乐观并发控制(OCC).来自维基百科:
...在提交之前,每个事务都会验证没有其他事务修改了它已读取的数据.如果检查显示有冲突的修改,则提交事务将回退...
实现OCC的方法是检查version要修改的数据.如果版本不同,那么其他事务已修改数据,并由应用程序决定如何解决冲突(重新尝试,通知用户......).
草案如下:
class Repository
{
public class save($data)
{
$currentVersion = $data->version;
$data->version = $currentVersion + 1;
$result = $this->db->update($data, [
'id' => $data->id,
'version' => $currentVersion
]);
if (1 === $result) {
// everything ok
} else {
// conflict!
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,因为EventSourcing我们只追加域中发生的所有事件,我们不能再使用这种方法来实现OCC.在使用EventSourcing时,哪些其他方法可以保留OOC?
一个可行的选项,它可以在存储时查找冲突事件.这种方法允许对事件进行细粒度控制.我不知道这是否会使解决方案复杂化,或者我认为这是一个"标准",我在http://danielwhittaker.me/2014/09/29/handling-concurrency-issues-cqrs-event-sourced指出-系统/
问题描述中的任何空白都是值得赞赏的.提前致谢!
默认情况下,乐观锁不适用于事件源,因为乐观锁需要锁定状态。在事件溯源中,您没有状态之类的东西,您只有事件列表(更改流)。正如已经多次提到的,您可以使用以下方法:
另请记住,您的事件存储应该允许您使用唯一索引,在这种情况下,RDBMS 表是最佳选择。
小智 5
应用事件溯源,您的表中还应该有一个版本字段,否则在构建聚合根时无法获取事件的顺序。但顺序很重要。您还可以利用此版本字段来支持 OCC。例如,如果您有竞争条件,例如两个具有相同 ID 和相同版本的事件几乎同时保存在事件存储中,则最后一个事件会丢失,并且如果您使用复合,则会引发重复键异常主键由聚合 ID 和版本组成。