views:

29

answers:

1

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?

+1  A: 

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.

Steven