DTO outdate mapping to database in C# - Domain Driven Design

c# dapper domain-driven-design entity-framework

Question

I am designning project structure follow DDD artchitecture & C# technologies. I am facing an issue with out date DTO mapping to Domain Model and persit the out date data to database.

The scenario as bellow

I have 2 distributed clients (Desktop) getting data for the Student has ID=1

  1. Server return DTO for Student has ID=1 with bellow information to Client 1 & 2 like that: Student:

    • ID = 1
    • Full Name: John;
    • Phone number: 01234;
  2. The Client 1 getting the DTO and Update phone number of this Student to: 56789 and permit the save action ---> Database have persited the new phone value to 56789.

  3. The Client 2 getting the DTO and Update Full name of this Student to: Peter and permit the save action ---> Database have persited the new Full name: Peter and the old phone number: 01234 (Un-expected behavior)

Root cause: - When perform Saving action, the client return the modified DTO to Server and mapping to Domain Model. The DTO keeping the old value (Phone number: 01234) and mapping this value to Domain Model.


Would you please advise me a way or a pattern or a technology for preventing this issue? This point is very important because the application can have multiple person modified the same application model at the same time.

Thank you so much

1
1
7/21/2017 10:40:38 AM

Popular Answer

It's called a concurrency problem. There are many ways to deal with it. RDMS products like SQL Server or Oracle, for example, have built-in concurrency handling features that can help (check your database vendor's documentation). Study and utilize them first, then add your preferred programmatic approach. I've seen the following done in some of the applications I supported, each with their own problems so you'll have to test what works best for your applications and how your users operate.

  • One way is to add a field to store the record's version (timestamp). When a user saves a record, check if the record's database version < version at hand. To increase integrity, you can also add checks to compare old values vs. current values vs. new values as well. Save if everything checks out fine, otherwise, "reject" and let the user know.
  • Another way is to add fields as lock flags (user ID + time stamp). When a user requests to edit a record, the lock flags get updated (with the user's ID + the current time). In the UI, the saved user ID "wins" edit mode, and all other users get read-only mode. When the editing user saves (or cancels) from the UI, the lock flags are cleared, setting the record ready for a new request to edit. Pro: users know when a record is locked by who and since what time; Con: you need to add features to "expire" a lock, or to let users "grab/steal" a lock.
  • Lastly, the solution can be operational, with users grouped to work on pre-assigned set/range of records (or on schedule) without overlaps. Primitive but works! It's user-behavior dependent, but can be a short-term solution while you're putting together your app's concurrency handling features. In most of the apps I supported, the planning and implementation for this approach end up becoming the users' SOP anyway, with the actual programmatic concurrency solution serving as an additional "safety check", JIC.

There are many other ways, each with their own problems as well. They can be simple to sophisticated. Named-patterns can include OCC, event sourcing and messaging, for example. Regardless, the assumption is that at least one request can win "first come, first serve" and all other requests handled to react accordingly.

Hope this helps!

0
7/21/2017 6:14:19 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow