In a multi-user system or application, concurrency is a major issue that the development team must address. Concurrency, in the context of a software application, is the handling of multiple users attempting to access the same data at the same time.
For example, consider a multi-user order processing system that allows users to add and edit orders for customers. Adding orders is not a problem-since each new order generates a discrete record, several users can simultaneously add orders to the database without interfering with one another.
Editing orders, on the other hand, can result in concurrency problems. When a user opens an order to edit it, a dialog is displayed on the local machine with information about that order. To accomplish this, the system retrieves the data from the database and stores it temporarily in the local machine’s memory, so the user can see and change the data. Once changes are made, the data is sent back to the server, and the database record for that order is updated. Now, if two users simultaneously have the editing dialog open for the same record, they both have copies of the data in their local machines’ memory, and can make changes to it. What happens if they both choose to save the data?
The answer depends on how the application is designed to deal with concurrency. Managing multi-user access to a shared resource is a challenge. Any resource that can be accessed by more than one user requires software logic to protect that resource by managing the way multiple users can access and change it at the same time. This problem has only become more common since the advent of network file sharing, relational databases, and client-server computing.
There are several ways for a software application to deal with concurrency. Among these are the following:
Pessimistic: This concurrency model places locks on data. If one user has a record open and any other users attempt to read that data in a context that allows editing, the system denies the request. In the preceding example, the first user to open the order for editing gets the lock on the order record. Subsequent users attempting to open the order will be sent a message advising that the order is currently being edited by another user, and will have to wait until the first user saves the changes or cancels the operation. This concurrency model is best in situations when it is highly likely that more than one user will attempt to edit the same data at the same time. The downside with this model is that others users are prevented from accessing data that any one user has open, which makes the system less convenient to use. There is also a certain amount of implementation complexity when a system must manage record locks.
Optimistic: In the optimistic concurrency model, users are always allowed to read the data, and perhaps even to update it. When the user attempts to save the data, however, the system checks to see if the data has been updated by anyone else since the user first retrieved it. If it has been changed, the update fails. This approach allows more users to view data than does the pessimistic model, and is typically used when it is unlikely that several users will attempt to edit the same data at the same time. However, it is inconvenient when a user spends time updating a record only to find that it cannot be saved. The record must be retrieved anew and the changes made again.
No concurrency protection: The simplest model of all, this approach does not attempt to protect users from editing the same data. If two users open a record and make changes, the second user’s changes will overwrite the first’s in a “last-one-wins” situation. The first user’s changes will be lost. Also, depending on how the system is implemented, this approach could lead to data corruption if two users attempt to save at the same moment.The way a software application deals with concurrency can affect the performance, usability, and data integrity of the system. Therefore, it is important to design tests to verify that the application properly handles concurrency, following the concurrency model that has been selected for the project.