001
014
015 package com.liferay.portal.kernel.lock;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.model.Lock;
022 import com.liferay.portal.service.LockLocalServiceUtil;
023
024 import java.util.Date;
025
026
029 public class LockProtectedAction<T> {
030
031 public LockProtectedAction(
032 Class<?> clazz, String lockKey, long timeout, long retryDelay) {
033
034 _className = clazz.getName();
035 _lockKey = lockKey;
036 _timeout = timeout;
037 _retryDelay = retryDelay;
038 }
039
040 public T getReturnValue() {
041 return _returnValue;
042 }
043
044 public void performAction() throws PortalException, SystemException {
045 Lock lock = null;
046
047 while (true) {
048 try {
049 lock = LockLocalServiceUtil.lock(
050 _className, _lockKey, _lockKey);
051 }
052 catch (Exception e) {
053 if (_log.isWarnEnabled()) {
054 _log.warn("Unable to acquire lock. Retrying.");
055 }
056
057 continue;
058 }
059
060 if (lock.isNew()) {
061 try {
062 _returnValue = performProtectedAction();
063 }
064 finally {
065 LockLocalServiceUtil.unlock(_className, _lockKey, _lockKey);
066 }
067
068 break;
069 }
070
071 Date createDate = lock.getCreateDate();
072
073 if ((System.currentTimeMillis() - createDate.getTime()) >=
074 _timeout) {
075
076 LockLocalServiceUtil.unlock(
077 _className, _lockKey, lock.getOwner());
078
079 if (_log.isWarnEnabled()) {
080 _log.warn("Removed lock " + lock + " due to timeout");
081 }
082 }
083 else {
084 try {
085 Thread.sleep(_retryDelay);
086 }
087 catch (InterruptedException ie) {
088 if (_log.isWarnEnabled()) {
089 _log.warn(
090 "Interrupted while waiting to reacquire lock", ie);
091 }
092 }
093 }
094 }
095 }
096
097 @SuppressWarnings("unused")
098 protected T performProtectedAction()
099 throws PortalException, SystemException {
100
101 return null;
102 }
103
104 private static Log _log = LogFactoryUtil.getLog(LockProtectedAction.class);
105
106 private String _className;
107 private String _lockKey;
108 private long _retryDelay;
109 private T _returnValue;
110 private long _timeout;
111
112 }