将并发冲突传达给应用层
当将并发冲突传达到应用程序层时,是否有使用异常的替代方法,并且也遵循 原则命令-查询分离,或者异常是我们拥有的最佳机制(在支持异常的语言中)?
在我的应用程序的内部,我有乐观锁定逻辑,当我调用某些高级方法时,它会执行几层,例如(在我的例子中,我正在使用自定义数据访问层,尽管我当然愿意听听 ORM 实现如何做到这一点)。应用程序与之交互的高级方法调用如下所示:
// 'data' is just a placeholder for multiple parameters, including something
// that contains row version information
void Customer.UpdateInformation(object data);
当其他人更新了他们正在处理的数据时,我需要能够告诉 Web 应用程序的用户。
我不想从更改数据的方法返回值。因此,在过去,我曾抛出异常(类似于 .NET 数据适配器 API,它会抛出 DBConcurrencyException 当它检测到冲突时),但从某种常识角度来看,并发冲突并不是例外。它们是生活中的一个事实:应用程序工作流程中可预测的、预期的部分。在 Eric Lippert 的文章中,它们是否符合外生异常的资格分类学?
When communicating concurrency conflicts to your application layer, is there an alternative to using exceptions that also respects the principle of Command-Query Separation, or are exceptions the best mechanism we have (in languages that support exceptions)?
In the bowels of my application, I have optimistic locking logic that executes a few layers down when I call certain high-level methods, e.g. (in my case, I'm using a custom data access layer, though I'm certainly open to hearing how ORM implementations do this). High level method calls that the application interacts with look like this:
// 'data' is just a placeholder for multiple parameters, including something
// that contains row version information
void Customer.UpdateInformation(object data);
I need to be able to tell users of a web application when someone else has updated the data they're working on.
I'd rather not return a value from methods that change data. So in the past, I've thrown exceptions (similar to the .NET data adapter API, which throws a DBConcurrencyException when it detects conflicts), but concurrency conflicts are not, in some common-sense way, exceptional. They're a fact of life: a predictable, expected part of the application's workflow. Do they qualify as exogenous exceptions, in Eric Lippert's taxonomy?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我看来,异常是传达此类错误的最佳方式。我认为您的解决方案是非常正确的,因为您抛出了一种可以在表示层捕获的特定类型的异常。表示层可以使用该异常中的信息来显示给用户。
虽然例外是最好的方法,但创建良好的用户体验可能非常困难。最简单的事情是告诉用户存在冲突,并选择他是想丢失更改还是覆盖新更改。当您想要显示冲突或让用户选择要覆盖哪些值以及不覆盖哪些值时,这会变得很困难。或者至少,很难以通用的方式做到这一点。您可能需要一个特定的界面来解决系统中可能发生冲突的每个屏幕的此类冲突。
在我工作的系统中,我们几乎没有捕捉到这些异常并向用户显示。我们主要试图通过改变冲突背后的流程来防止这些冲突的发生。当然,什么解决方案最好完全取决于您的应用程序类型以及业务工作方式(或喜欢工作方式)。
In my opinion Exceptions are the best way to communicate these kind of errors. I think your solution is quite right, because you throw a specific kind of exception that you can catch at the presentation layer. The presentation layer can use the information in that exception to display to the user.
While Exceptions are the best way, creating a nice user experience can be very hard. The simplest thing would be to tell the user that there was a conflict and choose if he would like to lose his changes or like to override the new changes. It gets hard when you want to display the conflicts or let the user choose which values to override and which not. Or at least, it is very hard to do this in a generic way. You possibly would need a specific interface for resolving such conflicts for each screen in your system where conflicts could occur.
In the systems I worked on, we hardly mostly didn't catch those exceptions for display to the user. We mostly tried to prevent those conflicts from occurring by changing the processes behind it. It of course totally depends on your application type and the way the business works (or likes to work) what solution is best.