1

我有 2 个处理程序删除和重新排序图片的运行订单,并希望获得一些最佳解决方案的建议。

在 UI 上一些图片被删除,用户点击删除按钮。整个流程,删除命令直到实际删除物理文件的事件处理程序被启动。

然后用户立即对剩余的图片进行分类。从重新排序命令到文件系统的重新排序事件处理程序的新流程再次触发。

已经存在并发问题。如果没有完成删除,则无法正确应用重新排序。目前这个问题是用某种锁来处理的。创建一个临时文件,然后在删除流程结束时将其删除。当该文件存在时,另一个线程(根据用户操作重新排序或删除)等待。

这不是一个理想的解决方案,并希望对其进行更改。潜在的解决方案也必须非常快(当然当前的解决方案不是很快的),因为 UI 在订购结束时通过 JSON 调用进行更新。

在稍后的实现中,我们正在考虑使用事件队列,但目前我们陷入了困境。

任何想法将不胜感激!谢谢你,摩苏'!

编辑:我们通过在客户端使用 Javascript 数据管理器解决了其他最终一致性问题。基本上是乐观主义者并欺骗用户!:) 我开始相信这也是去这里的方式。但是我怎么知道文件系统中的数据何时更改?

4

2 回答 2

0

Here is one thought on this. What exactly you are reordering? Pictures? Based on, say, date. Why there is command for this? The result of this command going to be seen by everyone or just this particular user?

I can only guess, but it looks like you've got a presentation question here. There is no need to store pictures in some order on the write side, it's just a list of names and links to the file storage. What you should do is to store just a little field somewhere in the user settings or collection settings: Date ascending or Name descending. So you command Reorder should change only this little field. Then when you are loading the gallery this field should be read first and based on this you should load one or another view. Since the store is cheap nowadays, you can store differently sorted collections on the read side for every sort params you need.

To sum up, Delete command is changing the collection on the write side, but Reoder command is just user or collection setting. Hence, there is no concurrency here.

Update

Based on your comments and clarifications.

  1. Of course, you can and, probably, should restrict user actions only by one at the time. If time of deletion and reordering is reasonably short. It's always a question of type of user experience you are asked to achieve. Take a usual example of ordering system. After an order placed, user can almost immediately see it in the UI and the status will be something like InProcess. Most likely you won't let user to change the order in any way, which means you are not going to show any user controls like Cancel button(of course this is just an example). Hence, you can use this approach here.
  2. If 2 users can modify the same physical collection, you have no choice here - you are working with shared data and there should be kind of synchronization. For instance, if you are using sagas, there can be a couple of sagas: Collection reordering saga and Deletion saga - they can cooperate. Deletion process started first - collection aggregate was marked as deletion in progress and then right after this reordering saga started, it will attempt to start the reordering process, but since deletion saga is inprocess, it should wait for DeletedEvent and continue the process afterwards.The same if Reordering operation started first - the Deletion saga should wait until some event and continue after that event arrived.

Update

Ok, if we agreed not touch the file system itself, but the aggregate which represents the picture collection. The most important concurrency issues can be solved with optimistic concurrency approach - in the data storage a unique constraint, based on aggregate id and aggregate version, is usually used.

Here are the typical steps in the command handler:

This is the common sequence of steps a command handler follows:

  1. Validate the command on its own merits.
  2. Load the aggregate.
  3. Validate the command on the current state of the aggregate.
  4. Create a new event, apply the event to the aggregate in memory.
  5. Attempt to persist the aggregate. If there's a concurrency conflict during this step, either give up, or retry things from step 2.

Here is the link which helped me a lot some time ago: http://www.cqrs.nu/

于 2013-04-19T18:45:03.127 回答
0

最大的建议非常受欢迎,通常它们适用。

有时很难解释实现的所有细节,但有一个细节应该提到:我们存储图片的方式意味着当重新排序时,所有图片路径(以及所有链接)都会发生变化。

一位同事想到了简单地删除这部分的好主意。这意味着即使顺序会改变图片的路径也将保持不变。在 UI 端,显示顺序中的图片索引与其路径之间会有一个映射,这意味着除了删除时,无需再更改文件系统。

由于我们希望对我们的用户尽可能宽容,这对我们来说是最好的解决方案。我认为,总的来说,当出现并发问题时,这也是一种好方法。可以去掉并发吗?

于 2013-04-24T07:22:03.933 回答