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