Image the situation where you have an enterprise system where you can edit customer records. Then think what if two people are are editing the same record. Both make some changes, but when they save which change will prevail? What if one saves over the other data? These are concurrency issues.
These are the one of the most complicated but still important issues in enterprise programming. Yet they are usually ignored by programmers. How do we make sure data is not lost when two or more users are working on the same data?
In this lecture we look at concurrency, transactions, execution contexts, the ACID database properties and try to apply them to enterprise programming where transaction usually span multiple requests, so called business transactions.
4. Concurrency
Enterprise system must support many
simultaneous users
– Need to guaranty correctness of data
Concurrency
– When computations overlap in time, and which may
permit the sharing of common resources between
those overlapped computations
– When two users are updating the same data, race
conditions can occur causing corrupt data
5. Concurrency Problems
Martin opens file to work with
David opens the same file, changes and finishes
before Martin and saves the file
Martin than saves his changes and David's
changes are lost
Lost update
6. Concurrency Problems
Martin needs to know how many files are in the
concurrency package
The package contains two sub-packages
Martin counts the number in first package, then
becomes busy
In the meantime David adds new files to both
packages
Then Martin continues and counts the files in the
second package
Inconsistent read
7. Concurrency Problems
Both problems cause a failure of correctness
– Result when two people are working on the same
data at the same time
To avoid these problems and provide
correctness we must lock access to the data
– Only one person can work on the data at the same
time
– Provides correctness
– Reduces concurrency
Liveness suffers
– How much concurrent activity can go on
8. Execution Contexts
Processing occurs in some context
– Two important contexts: request and session
Request
– Single call from outside, system sends response
Session
– Long-running interaction between client and server
– Multiple requests that must be linked together
– Example: user logs in, places items in a shopping
cart, buys, logs out
9. Isolation
Partition the data so that any piece of it can only
be accessed by one active agent (program or
thread)
Only one thread can enter critical section or
isolated zone Inconsistent read
at each
10. Immutability
Concurrency problems occurs for data that can
be modified
By recognizing immutable data we can relax
concurrency concerns and share it widely
Inconsistent read
11. EXCERISE
Two users of a source control system want to work on the
same file at the same time. How can we make sure that data is
not lost?
12. Concurrency Control
Control of mutable data that we can’t isolate
Pessimistic locking
– Martin opens the file
– When David wants to open the file, he’ll get denial,
saying it is already in use
– Conflicts avoidance
13. Concurrency Control
Control of mutable data that we can’t isolate
Optimistic locking
– Martin and David both edit the same file
– David finishes first and saves
– Then Martin saves, he’ll get an error since David has
updated the file
– Conflict detection
14. Concurrency Control
Problem with pessimistic locking
– Avoids concurrency and reduces efficiency
Optimistic locking provide more efficiency
– Locks are only used on commit
– The problem is what happens on conflicts
Which one to use?
– Based on frequency and severity of conflicts
– If conflicts are sufficiently rare or if the consequence is not
great, optimistic locking works better
– If conflicts are frequent and painful, pessimistic locks are
better
15. Preventing Inconsistent Reads
Inconsistent Reads
– Martin edits the Customer class and adds some calls
to the Order class. Meanwhile David edits the Order
class and changes the interface. David compiles and
checks in. Martin compiles and checks in. Now the
shared code is broken.
How to avoid this?
– Pessimistic Lock
• Avoids the problem
– Optimistic Locks
• Detects the problem
16. Preventing Inconsistent Reads
Pessimistic Lock
– To read data you need a read lock and to write data you
need to have write lock
– Many can have read lock, but if anyone has read lock,
nobody can get write lock
– If anyone has write lock, nobody can get read lock
– Can lead to Dead-lock
Optimistic Locks
– Use timestamps or sequence number for version
marker
– If someone tries to commit broken code it is detected and
needs manual fix
17. Deadlock
When two or more are waiting for each other
– David is using the Order file and is waiting for the
Customer file, but Martin has the Customer file and
is waiting for the Order file.
– This can happen in the pessimistic approach
Solutions
– Detect the deadlock and find a victim
– Release resources from the victim so other can
progress
– Use timeouts
18. Transactions
Transaction is a bounded sequence of work
– Both start and finish is well defined
– Transaction must complete on an all-or-nothing basis
All resources are in consistent state before and
after the transaction
Example: Database transaction
– Withdraw data from account
– Buy the product
– Update stock information
Transactions must have ACID properties
19. ACID properties
Atomicity
– All steps are completed successfully – or rolled back
Consistency
– Data is consistent at the start and the end of the
transaction
Isolation
– Transaction is not visible to any other until that transaction
commits successfully
Durability
– Any results of a committed transaction must be made
permanent
20. Transactional Resources
Anything that is transactional
– Use transaction to control concurrency
– Databases, printers, message queues
Transaction must be as short as possible
– Provides greatest throughput
– Should not span multiple requests
– Long transactions span multiple request
21. Transaction Isolations and
Liveness lock tables (or resources)
Transactions
– Need to provide isolation to guarantee correctness
– Liveness suffers
– We need to control isolation
Serializable Transactions
–
–
–
–
Full isolation
Transactions are executed serially, one after the other
Benefits: Guarantees correctness
Drawbacks: Can seriously damage liveness and
performance
22. Isolation Level
Problems can be controlled by setting the
isolation level
– We don’t want to lock table since it reduces
performance
– Solution is to use as low isolation as possible while
keeping correctness
23. Phantoms
Description
– Transaction A reads rows. Transaction B adds (INSERT) a
new row. A reads rows again, but now a new row has been
added, “phantom” row.
– Repeatable Read isolation level
24. Unrepeatable Read
Description
– Transaction A reads value. Transaction B updates the
value. A repeats the read but now the value is
different.
– Read Committed isolation level
25. Dirty Read
Description
– Transaction A reads and updates value. Transaction B
reads the value. Then A rollbacks and resets value. B
updates value.
– Read uncommitted isolation level
26. Isolation Level
Problems can be controlled by setting the
isolation level
– We don’t want to lock table since it reduces
performance
– Solution is to use as low isolation as possible while
keeping correctness
27. Transactions
Pull together several requests that the clients
wants treated as if they were a single request
System Transactions
– From the Application to the Database
Business Transaction
– From the User to an Application
– Transactions that expand more than one request
28. Offline Concurrency
Need ACID properties for Business Transactions
– Problem is with locking
– Application won’t be scalable because long
transactions will turn the database into a major
bottleneck
Solution
– Business Transaction are broken into short system
transactions
– System must provide ACID properties between
system calls
29. Optimistic Offline Lock (416)
Prevents conflicts between concurrent business
transactions by detecting and rolling back the
transaction
How It Works
– Validates chances to data when committed
– If someone else has in the meantime updated,
changes are not committed
– Based on version counters
– Can provide old and new version for comparisons
When to Use It
– When chance of conflict is low, resolution is not too
hard
31. Pessimistic Offline Lock (426)
Prevents conflicts between concurrent business
transactions by allowing only one business
transaction at a time to access data
How It Works
– Prevents conflicts by avoiding them
– Data is locked so it cannot be edited
– Locks can be: exclusive write lock, exclusive read lock,
read/write lock
– Can be controlled by the application or the database
When to Use It
– When data must be isolated and conflicts are likely
35. Example
Table customer
create table customer
(
id int Identity (1, 1) primary key NOT NULL,
modifiedby varchar(32),
modified datetime,
version int,
name varchar(32)
)
36. Example
Data Transfer Object reflects the customer
table
public class Customer
{
private int id;
private Date modified;
private String modifiedBy;
private int version;
private String name;
...
37. Example
Layered Supertype for Data Mappers
package is.ru.honn.data;
import javax.sql.DataSource;
public abstract class AbstractMapper
{
private String owner;
private DataSource dataSource;
protected AbstractMapper()
{
}
...
}
38. Example
CustomerMapper
public class CustomerMapper extends AbstractMapper
{
public Customer find(int id)
{
JdbcTemplate tpl = new JdbcTemplate(getDataSource());
return (Customer) tpl.query("select * from customer where id=" + id,
new CustomerRowMapper()).get(0);
}
39. Example
CustomerMapper
public void update(Customer customer) throws ConcurrencyException
{
Customer current = find(customer.getId());
if (current.getVersion() > customer.getVersion())
throw new ConcurrencyException("Customer has been changed by " +
current.getModifiedBy() + " at " +
current.getModified() + " (version: " + customer.getVersion() + ")");
JdbcTemplate tpl = new JdbcTemplate(getDataSource());
tpl.update("update customer set name=?, modifiedby=?, modified=?, " +
"version=? where id=?",
new Object[]
{
customer.getName(),
this.getOwner(),
new Date(),
customer.getVersion() + 1,
40. Example
public static void main(String[] args)
{
Resource resource = new FileSystemResource("data.xml");
BeanFactory beanfactory = new XmlBeanFactory(resource);
CustomerMapper mapperMartin = (CustomerMapper)beanfactory.getBean("customerMa
mapperMartin.setOwner("Martin");
CustomerMapper mapperDavid = (CustomerMapper)beanfactory.getBean("customerMap
mapperDavid.setOwner("David");
Customer custM = mapperMartin.find(1);
custM.setName("Mr. Stimpson J. Cat");
Customer custD = mapperDavid.find(1);
custD.setName("Ren Hoek");