4

Here is a theoretical problem. It could apply to many systems. Let's assume RESTful Web services for example. You want to find out something but as it happens you can't get it in a single query. You can make multiple queries. For example, you have a joint bank account (or a company bank account) and you want to find out how much money is in there. Meanwhile someone else transfers money from checking to savings.

Checking:  $5,000   Savings:  $3,000

Me: Query Checking. Response: $5,000

 

Joe: Transfer $4,000 from Checking to Savings

Checking: $1,000   Savings:  $7,000

Me: Query Savings. Response: $7,000

Total $12,000.

How do you avoid anomalies like this? The example shows two accounts at one bank, but it can also happen with two accounts at two different banks.

3 Answers 3

4

You need some form of concurrency control to deal with problems like this.

Some possible solutions in your example:

  1. Ensure that the service can return both Savings and Checking figures in a single query, perhaps as a Total.
  2. Implement some kind of session so that the user requesting values can lock the data until she has finished reading all the values in which she is interested. This approach is often called "pessimistic concurrency control".
  3. Design the service so that you can pass your previous Checking figure back when you request a Savings figure. If the Checking figure no longer matches its previous value, the service should indicate an error rather than return a value for Savings. This approach is a variation of "optomistic concurrency control".
6
  • +1 for the first solution. Commented Sep 23, 2010 at 16:59
  • @John - I was gonna suggest that but hypothetically the question implied that this was not possible. Commented Sep 23, 2010 at 17:06
  • In the case where only one service is involved, this is possible by adding functionality to the service. 1 and 3 are good. 2 would lock out all other users until the first is finished. It works for rest rooms but not for high-volume web sites. In the case of multiple services, for instance checking at www.chase.com and savings at www.wachovia.com, it's a more difficult problem. Commented Sep 24, 2010 at 16:29
  • @Mark: You're right, 2 would prevent other users updating data (but not reading it). In many cases this is unacceptable. In other situations, lost or delayed transactions are less costly than faulty reads. As you suggest, you have to take each case on its merits. An interesting variation: I query Checking, and lock it for updates. Joe's update for Checking gets added to a pending queue. I query Savings and release the lock on Checking. Joe's pending transaction gets committed.
    – Kramii
    Commented Sep 26, 2010 at 5:20
  • @Mark: With 2 services, things are indeed more tricky. If you can't coordinate them behind the scenes then you may be ot of luck.
    – Kramii
    Commented Sep 26, 2010 at 5:28
0

Assuming this is a secure API you could only allow one user to view/edit an account at any given time. So the credentials might look like this:

    User: Joe
    Password: dog
    Account: Z123456X

Once the user logs in a timed lock is started that is reset with every query to the API. If they log out the lock is completely removed. If this is impossible then there really isn't much you can do. There is always going to be race conditions when dealing with data like this. The best you can do when someone queries the API is return the actual value as well as the pending value based of any pending transactions. This minimizes the chance of stale data.

    Actual: $5,000 
    Pending: $1,000
0

This is why there are processes to indicated cleared and pending activity. Just like you would have both the withdrawal and the deposit in the same transaction, the balances have to be coorinated and indicate that there are pending transfers, so all balances may not be available.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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