You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Lock used in CheckoutServiceImpl#performCheckout exists in memory. It is used to prevent concurrent checkout for a same order. Before a checkout request is processed, it will acquire a lock from memory and release it after process. Once the lock can not be acquired, then the process will terminate, as show below.
protectedstaticConcurrentMap<Long, Object> lockMap = newConcurrentHashMap<>();
publicCheckoutResponseperformCheckout(Orderorder) throwsCheckoutException{
ObjectlockObject = lockMap.putIfAbsent(order.Id, newObject());
if(lockObject != null){
// orderId exists in lockMapthrownewCheckoutException("this order is already in process of being submitted");
}
if(hasOrderBeenCompleted(order)){
thrownewCheckoutException("order has been submitted");
}
try{
// do checkout
}
...
finally{[CheckoutServiceImpl#performCheckout]()
}
CartStateFilter (Database based lock)
Lock used in CartStateFilter is based on database. Every POST requests that try to modify order (including add cart, apply offer code, and checkout), must acquire a lock on the order first.The detail logic to determine whether a request need to acquire lock for order is in CartStateFilter#requestRequiresLock.
This lock is implemented through accessing a table named BLC_ORDER_LOCK as shown below:
begin# acquire lockselect# if there is no record, then create with INSERT count(*)
from
BLC_ORDER_LOCK
where
ORDER_ID =88and LOCK_KEY ='1a924f96-f039-4b48-ab5d-63ca7124a4ba'update# no rows affected means acquire lock failed
BLC_ORDER_LOCK
set
LOCKED ='Y',
LAST_UPDATED =1604653067663where
ORDER_ID =88and (
LOCKED ='N'or LAST_UPDATED <-1
)
and LOCK_KEY ='1a924f96-f039-4b48-ab5d-63ca7124a4ba'commit
... # process requestbegin# release lockupdate BLC_ORDER_LOCK set LOCKED='N'where ORDER_ID=88and LOCK_KEY='1a924f96-f039-4b48-ab5d-63ca7124a4ba'commit
This lock based on database is able to prevent concurrent modification for the same order, which including checkout. Therefore, memory lock used in CheckoutServiceImpl#performCheckout is redundant
Problem
The memory lock in CheckoutServiceImpl#performCheckout seems redundant, because lock used in CartStateFilter already prevent concurrent checkout.
Detail Description
performCheckout (Memory based lock)
Lock used in CheckoutServiceImpl#performCheckout exists in memory. It is used to prevent concurrent checkout for a same order. Before a checkout request is processed, it will acquire a lock from memory and release it after process. Once the lock can not be acquired, then the process will terminate, as show below.
CartStateFilter (Database based lock)
Lock used in CartStateFilter is based on database. Every POST requests that try to modify order (including add cart, apply offer code, and checkout), must acquire a lock on the order first.The detail logic to determine whether a request need to acquire lock for order is in CartStateFilter#requestRequiresLock.
This lock is implemented through accessing a table named BLC_ORDER_LOCK as shown below:
This lock based on database is able to prevent concurrent modification for the same order, which including checkout. Therefore, memory lock used in CheckoutServiceImpl#performCheckout is redundant
Suggestion
Maybe memory lock in CheckoutServiceImpl#performCheckout can be removed to obtain better performance.
The text was updated successfully, but these errors were encountered: