Showing posts with label @Transactional. Show all posts
Showing posts with label @Transactional. Show all posts

Wednesday, October 25, 2017

Enterprise Application Architecture Design Patterns - Offline Concurrency Locks


Optimistic Offline Lock

it is used when the conflicts are rare. A compensation strategy should be ready when a conflict is found.

In Hibernate, it could be created by using @Version annotation to create a column with version number or a timestamp:


@Entity
public class Flight implements Serializable {
...
    @Version
    @Column(name="version")
    public Integer getVersion() { ... }
}   


@Entity
public class Flight implements Serializable {
...
    @Version
    public Date getLastUpdate() { ... }
} 

Pessimistic Offline Lock

A ReentrantLock could be used inside Java Classes to manage the concurrency control.
In Hibernate, pessimistic offline lock mechanism is also provided:


Session.lock(object, LockMode);


LockMode.WRITE, LockMode.READ could be used.
For Oracle database, two extra lock modes are provided for efficiency:


LockMode.WRITE
acquired automatically when Hibernate updates or inserts a row.
LockMode.UPGRADE
acquired upon explicit user request using SELECT ... FOR UPDATE on databases which support that syntax.
LockMode.UPGRADE_NOWAIT
acquired upon explicit user request using a SELECT ... FOR UPDATE NOWAITin Oracle.
LockMode.READ
acquired automatically when Hibernate reads data under Repeatable Reador Serializable isolation level. It can be re-acquired by explicit user request.
LockMode.NONE
The absence of a lock. All objects switch to this lock mode at the end of a Transaction. Objects associated with the session via a call to update() orsaveOrUpdate() also start out in this lock mode.


Coarse Grained Lock

In term of Domain Driven Design, an aggregate could be a candidate for applying coarse grained lock to reduce the chances of deadlocks.

Implicit Lock

If @Transactional is used in a Spring Framework based application, it could be put into Remote Facade or Session Facade to manage the transaction, then object retrieved from Repository may not need to handle the transaction directly. 

When using Spring @Transactional, please note that:

The Spring team's recommendation is that you only annotate concrete classes with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this will only work as you would expect it to if you are using interface-based proxies.