在信用交易系统上实施事件采购

时间:2017-10-01 23:16:25

标签: design-patterns event-sourcing

目前,我们有一个处理信用额度和借记的系统。

它将每个操作存储为数据库中的事务事件,但总而言之,我们仍然会更新" credit_bank"表示用户当前余额的表。

          Table "public.credit_bank"
     Column     |          Type          | Modifiers 
----------------+------------------------+-----------
 id             | bigint                 | not null
 user_id        | bigint                 | 
 currency       | character varying(255) | 
 amount         | numeric(40,10)         | not null


                 Table "public.transaction"
      Column      |            Type             | Modifiers 
------------------+-----------------------------+-----------
 id               | bigint                      | not null
 amount           | numeric(40,10)              | not null
 credit_bank_id   | bigint                      | 
 status           | character varying(255)      | not null
 transaction_date | timestamp without time zone | 
 type             | character varying(255)      | not null

由于我们一次处理大量交易,因此每次更新时都会被锁定信用表以避免陈旧问题。

然后我遇到了事件采购。在这种情况下,这种模式是否适用?

我对此非常陌生,所以如果我出错了,请告诉我。

根据我的理解,如果我们使用事件源,我们就不需要存储" credit_bank"的状态,而是使用事件来提出状态,或者使用快照。但是如何确保目前的平衡仍然充足。

另外,如果我们每次都通过处理事件来获得状态,那会不会对性能造成影响?

2 个答案:

答案 0 :(得分:2)

  

这种模式适用于这种情况吗?

这听起来像是我在尝试描述某些角落情况时使用的一个例子,所以我想是的。

  

根据我的理解,如果我们使用事件源,我们就不需要存储“credit_bank”的状态,而是使用事件来提供状态,或者使用快照。但是如何确保目前的平衡仍然充足。

这些交易是来自您的商业模式,还是世界各地银行向您汇报的事情。因为如果是后者,那么你需要考虑“当前”平衡意味着什么 - 在远程银行向您发送交易之后但在该交易获得之前,您正在查询现在记录在您的数据库中。余额是否仍然“最新”?

由于信息来自“其他地方”,我们通常不会对时间做出原始假设。所以不是,“当前的平衡”,而是“时间上的平衡= t”。或者“时间上的余额= t1,当最近可用的更新时间= t2”时

换句话说,您开始包括时间建模,并与业务部讨论可用延迟是否“足够好”,使延迟更短的成本是什么,不是使延迟更短,等等。

  

如果我们通过每次处理事件来获得状态,那会对性能有害吗?

可能是。通常情况下,事件采购与相结合;这是另一种延迟权衡 - 更新模型的责任与查询模型的责任分开,只需要一些管道就可以将新数据从更新模型复制到查询模型。

答案 1 :(得分:0)

  

由于我们一次处理大量交易,因此每次更新时都会被锁定信用表以避免陈旧问题。

您可能需要使用数据库事务(我没有引用金融交易)以保持两个表的一致性。这会损害性能和可扩展性。

  

然后我遇到了事件采购。在这种情况下,这种模式是否适用?

事件采购非常适合仅附加系统,所以是的。

  

根据我的理解,如果我们使用事件源,我们就不需要存储“credit_bank”的状态,而是使用事件来提供状态,或者使用快照。但是如何确保目前的平衡仍然充足。

在每个withdrawMoneyFromTheAccount命令之前,您重播该帐户上的所有财务交易并计算当前余额;然后将交易金额与该余额进行比较,并允许或拒绝交易。

  

另外,如果我们每次都通过处理事件来获得状态,那会不会对性能造成影响?

对于锁定,您应该使用version列使用乐观锁定,而不是使用悲观锁定(如事务)。获得性能的真正好处是因为使用事件源只需要保护一个表,事件存储,而不是两个必须保持同步的表,就像在当前架构中一样。