目前,我们有一个处理信用额度和借记的系统。
它将每个操作存储为数据库中的事务事件,但总而言之,我们仍然会更新" 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"的状态,而是使用事件来提出状态,或者使用快照。但是如何确保目前的平衡仍然充足。
另外,如果我们每次都通过处理事件来获得状态,那会不会对性能造成影响?
答案 0 :(得分:2)
这种模式适用于这种情况吗?
这听起来像是我在尝试描述某些角落情况时使用的一个例子,所以我想是的。
根据我的理解,如果我们使用事件源,我们就不需要存储“credit_bank”的状态,而是使用事件来提供状态,或者使用快照。但是如何确保目前的平衡仍然充足。
这些交易是来自您的商业模式,还是世界各地银行向您汇报的事情。因为如果是后者,那么你需要考虑“当前”平衡意味着什么 - 在远程银行向您发送交易之后但在该交易获得之前,您正在查询现在记录在您的数据库中。余额是否仍然“最新”?
由于信息来自“其他地方”,我们通常不会对时间做出原始假设。所以不是,“当前的平衡”,而是“时间上的平衡= t”。或者“时间上的余额= t1,当最近可用的更新时间= t2”时
换句话说,您开始包括时间建模,并与业务部讨论可用延迟是否“足够好”,使延迟更短的成本是什么,不是使延迟更短,等等。
如果我们通过每次处理事件来获得状态,那会对性能有害吗?
可能是。通常情况下,事件采购与cqrs相结合;这是另一种延迟权衡 - 更新模型的责任与查询模型的责任分开,只需要一些管道就可以将新数据从更新模型复制到查询模型。
答案 1 :(得分:0)
由于我们一次处理大量交易,因此每次更新时都会被锁定信用表以避免陈旧问题。
您可能需要使用数据库事务(我没有引用金融交易)以保持两个表的一致性。这会损害性能和可扩展性。
然后我遇到了事件采购。在这种情况下,这种模式是否适用?
事件采购非常适合仅附加系统,所以是的。
根据我的理解,如果我们使用事件源,我们就不需要存储“credit_bank”的状态,而是使用事件来提供状态,或者使用快照。但是如何确保目前的平衡仍然充足。
在每个withdrawMoneyFromTheAccount
命令之前,您重播该帐户上的所有财务交易并计算当前余额;然后将交易金额与该余额进行比较,并允许或拒绝交易。
另外,如果我们每次都通过处理事件来获得状态,那会不会对性能造成影响?
对于锁定,您应该使用version
列使用乐观锁定,而不是使用悲观锁定(如事务)。获得性能的真正好处是因为使用事件源只需要保护一个表,事件存储,而不是两个必须保持同步的表,就像在当前架构中一样。