Repository navigation
feat(concurrency): lock several aggregates in a fixed order - #75
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
@AggregateLockandAggregateLocks.executelock one aggregate. Reserving stock for an order changes one stock aggregate per order line, so it needs several locks at once. Nestingexecutecalls by hand acquires them in whatever order the caller passes the IDs: one order locking A then B and another locking B then A can each hold one lock and wait for the other until the wait time runs out. This came up in the inventory context ofddk-mall.Changes
AggregateLocks.executeAll(type, ids, action)acquires the locks sorted by lock name, runs the action while holding all of them, and releases them in reverse order. Duplicate IDs are locked once.AggregateBusyExceptionis thrown.背景
@AggregateLock和AggregateLocks.execute锁的是一个聚合。为订单预占库存时,每个订单行都要修改一个库存聚合,需要同时持有多把锁。自己嵌套调用execute时,加锁顺序取决于调用方传入标识的顺序:一个订单先锁 A 再锁 B,另一个先锁 B 再锁 A,就可能各持有一把、互相等对方那一把,直到等待超时。这个问题是在ddk-mall的库存上下文里遇到的。改动
AggregateLocks.executeAll(type, ids, action):按锁名排序后依次加锁,持有全部锁期间执行操作,再按相反顺序释放。重复的标识只锁一次。AggregateBusyException。加锁顺序见上文示意。