Home > database >  How to realize the column level optimistic locking
How to realize the column level optimistic locking

Time:09-19

The concurrency control mechanism, pessimistic and optimistic locking, are based on the line, for some of the many modules can access and modify data column is not the same (change), the particle size is not enough, because of different modules of the business, the modified field is not necessarily the same (or the same class),
In these scenarios, based on the column of concurrency is meaningful, can greatly increase the ability of concurrent transactions executed in this paper, we introduce the optimistic locking mechanism that is based on the realization of the memory, lock acquisition and concurrent test, is entirely in memory, will not have any interaction and database, so efficiency is very high,

First is to increase transaction interceptor, at the beginning of the transaction registration transaction information, at the end of the transaction to clear transaction information
@ Override
Public Object invoke (the MethodInvocation invocation) throws Throwable {
//transaction information
TransactionStatus TransactionStatus=TransactionUtils
GetCurrentTransactionStatus ();
TransactionInfo TransactionInfo=null;
Boolean bind=false;
If (transactionStatus!=null & amp; & TransactionStatus. IsNewTransaction ()) {
TransactionInfo=new transactionInfo (invocation, transactionStatus);
TransactionInfoManager. AddTransactionInfo (transactionInfo);
TransactionInfo. BindToThread ();
The bind=true;
Try {
TransactionSynchronizationManager
RegisterSynchronization (new OptimisticLockTransactionSynchronizationAdapter (
OptimisticLockManager transactionInfo));
} the catch (Exception e) {
e.printStackTrace();
}
}
Object the rv;
Try {
The rv=invocation. Proceed ();
} the finally {
If (transactionInfo!=null) {
TransactionInfoManager. RemoveTransactionInfo (transactionInfo);
}
If (bind) {
TransactionInfo. RestoreThreadLocalStatus ();
}
}
Return the rv.
}
OptimisticLockTransactionSynchronizationAdapter code below
Public class OptimisticLockTransactionSynchronizationAdapter extends
TransactionSynchronizationAdapter {

Private TransactionInfo TransactionInfo=null;
Private OptimisticLockManager OptimisticLockManager;

Public OptimisticLockTransactionSynchronizationAdapter (
OptimisticLockManager OptimisticLockManager,
TransactionInfo TransactionInfo) {
super();
Enclosing transactionInfo=transactionInfo;
Enclosing optimisticLockManager=optimisticLockManager;
}

@ Override
Public void afterCompletion (int status) {
//when the transaction is complete, remove the transaction related lock
OptimisticLockManager. ReleaseTransactionLocks (transactionInfo);
}
}
TransactionInfo class for the transaction information, in the current thread will have a stack, each time a new transaction will generate a new TransactionInfo object, and into the stack, after the end of the transaction, will the current TransactionInfo stack, the diagram below:


The following is the core of the relevant class
Class OptimisticLockManager
Properties private ConcurrentHashMap EntityToLocksMap
Public void requestLock (String entity, String the rowId, String colId) {

EntityLocksInfo EntityLocksInfo=entityToLocksMap. Get (entity);

If (entityLocksInfo==null) {
EntityLocksInfo newEntityLocksInfo=new EntityLocksInfo (entity);
EntityLocksInfo=entityToLocksMap. PutIfAbsent (entity,
NewEntityLocksInfo);
If (entityLocksInfo==null) {
EntityLocksInfo=newEntityLocksInfo;
}
}

EntityLocksInfo. RequestLock (rowId, colId);
}

Class EntityLocksInfo
Properties private ConcurrentHashMap IdToRowLocksInfoMap
Public void requestLock (String rowId, String colId) {
TransactionInfo TransactionInfo=TransactionUtils
CurrentTransactionInfo ();
If (transactionInfo==null) {
Throw new OptimisticLockNoTransactionException ();
}
RowLocksInfo RowLocksInfo=idToRowLocksInfoMap. Get (the rowId);

If (rowLocksInfo==null) {
RowLocksInfo newRowLocksInfo=new RowLocksInfo (entity);
RowLocksInfo=idToRowLocksInfoMap. PutIfAbsent (rowId,
NewRowLocksInfo);
If (rowLocksInfo==null) {
RowLocksInfo=newRowLocksInfo;
}
}
RowLocksInfo. RequestLock (colId);
}

Class RowLocksInfo
Properties private ConcurrentHashMap ColIdToLockMap
Methods the public void requestLock (String colId);
Public void requestLock (String colId) {
TransactionInfo TransactionInfo=TransactionUtils
CurrentTransactionInfo ();
If (transactionInfo==null) {
Throw new OptimisticLockNoTransactionException ();
}
OptimisticLock existingOptimisticLock=colIdToLockMap. Get (colId);
If (existingOptimisticLock==null) {
OptimisticLock newOptimisticLock=new OptimisticLock ();
NewOptimisticLock. SetId (colId);
NewOptimisticLock. SetTransactionInfo (transactionInfo);

ExistingOptimisticLock=colIdToLockMap. PutIfAbsent (colId,
NewOptimisticLock);
If (existingOptimisticLock==null) {
TransactionInfo. AddLock (newOptimisticLock);
}
}
If (existingOptimisticLock!=null) {
If (existingOptimisticLock. GetTransactionInfo ()!={transactionInfo)
Throw new OptimisticLockConflictException (colId,
TransactionInfo);
}
}

}

Class OptimisticLock by real objects, recorded the lock's real name, id, id, etc.

Private String entity;
Private String rowId.
Private String colId;


How to use the
in business class
The business manager to inject OptimisticLockManager
Have a product management system, for example, there are three products, the following data in the database

nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related