1

All of the enterprise projects I work on seem to follow the same pattern.

  • A request is issued to the server (from a client or Api)
  • The server side loads some data from a database
  • Modifies the data in some way
  • Commits the changes to the database

E.g.

//Client after user click cancel on the order screen
_apiClient.Execute(new CancelOrder(_orderId)) ;

//On server in CancelOrderHandler
var order =_db.Orders.Single(o => o.Id == command.OrderId);
 order.Cancel();
_db.Orders.Update(order);
_db.CommitTransaction();
_db.SaveChanges();

This is pretty simple and easy to understand, but given this method (pattern?) is used everywhere I wonder if we are doing something wrong in some cases?

In this case could you consider the database to effectively be global state? Given 2 clients could access the same data at the same time?although they would have different instances.

Are there better ways to handle a command and commit some action because of it? Or is loading the latest domain object from a database, changing it and committing the changes always the way to go?

  • Keep in mind that you don't "load from a database", you copy the data from it to your c# app and them send back a command to change it. The objects in memory and the SQL Database have absolutely nothing to do with each other - is your ORM that takes care of abstracting that out and making it seems that they are a single thing. Records aren't "things" you load. – T. Sar Jul 5 '17 at 18:10
  • But, well, yes - unless you want to have some issues with different versions of the objects floating around on your workstations, query-update-commit is the way to go. – T. Sar Jul 5 '17 at 18:13
  • 1
    For how long have you been working for the industry? (Software engineery) – Laiv Jul 5 '17 at 18:56
  • 1
    There are at least two questions here. First is about concurrency of accessing same record and second is if load/update is best way. First is extremely broad topic. And for second, event sourcing comes to mind as alternative. – Euphoric Jul 5 '17 at 18:58
  • @Laiv about 7 years professionally – Nick Williams Jul 5 '17 at 19:32
1

In designing client-server database solutions, the server is recognized as the data authority and is the repository of the latest, most up to date, records pertaining to the application. So the pattern you describe is widely used.

Solving the problem of simultaneous access can be approached in several ways. I have personally used the 'optimistic update' solution, with part of the WHERE clause for the update being the last modification time read from the record by your client. If your update changes no rows, someone has changed your record in the meantime, and you need to refresh and start again.

Another approach to solving near simultaneous updates is an 'ownership' state field and associated owner singleton processes that modifies the record once ownership has been obtained. This kind of approach is often implemented in business logic on the web server.

  • I tend to also use optimistic concurrency also, the order object above is an aggregate root with a version field – Nick Williams Jul 5 '17 at 19:34
0

Not necessarily

This is the simplest answer I think. Let me explain.

The 4-steps-execution-pattern.

Btw, your "pattern" remind me the Unit of work pattern.

 I wonder if we are doing something wrong in some cases?

Not necessarily. If we assume that the underlaying purpose of any enterprise application is:

  1. Collect data
  2. Data processing
  3. Store data
  4. Serve data

We come to the conclusion that there could be different ways to achieve this goal. However, the differences will be mere implementation details.

The 4-steps-execution-pattern would look different in distributed system, where the business transactions are not always ACID.

Are distributed systems the way to go? Hell no!! It depends on the needs.

The way to go is (or should be) the way that works for you. The solution, repetitive or not, should meet your requirements and expectations. If you have found the pattern that works, (lucky you!), what's wrong with that? As soon as it's adequate, the other strategies (patterns) don't matter.

The concurrency

In this case, could you consider the database to effectively be global state? Given 2 clients could access the same data at the same time? although they would have different instances.

Not necessarily, but generally yes, it's. Unless you can ensure that there will be one and only one access point to the DB and no concurrency at all. Could you? It's possible, but is it what you usually need?

Regarding the concurrency control. There's no silver-bullet solution. To be honest, near the 99% of my projects, the policy is LIW (Last In Wins). Scary? Not really. Concurrency control is required in very specific situations, so if I don't need it, why should I worry?

The good, the better and the best

Are there better ways to handle a command and commit some action because of it?

No necessarily. There're not better or worse ways. There are different approaches with different results. The one you need is the one that best suits your requirements. The key word here is adequacy.

On the other hand, perhaps, you might be interested in design patterns like CQRS. But read carefully about its adequacy.

0

Or is loading the latest domain object from a database, changing it and committing the changes always the way to go?

No it's not always. In your example it's not clear what order.Cancel() does but if we assume it just updates a status then executing a stored procedure passing the order id would save a bunch of network activity, ORM work and concurrency issues. If there's a ton of rules to apply maybe this is the correct approach. Where there's a large number of such things to do with little to no business logic it's mostly better to take the set based approach directly on the DB.

Like all things, generally the answer is 'it depends'. Don't get dogmatic or caught up in patterns for their own sake.

  • Just realised I've somehow necro'd this question. Sorry! – LoztInSpace Aug 5 '17 at 9:50
0
> Is always loading data from a database a design flaw?

Short answer: No it is not a flaw but a desgin decission

This assumed design flaw is called Stateless server pattern

If you implement a webserverver/webservice you have to decide if and how much data is stored in the session to make a tradeoff between performance (i.e. always requery the database) and memory consumption (i.e. cache last database result)

If performance is not good enough you can either use a servercluster (several servers running the same app) or you can optimize caching.

Caching can make the app much more complicated/errorprone so it is design decision

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.