View Javadoc
1   /*
2    * Copyright (c) 2001-2017, Zoltan Farkas All Rights Reserved.
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   *
18   * Additionally licensed with:
19   *
20   * Licensed under the Apache License, Version 2.0 (the "License");
21   * you may not use this file except in compliance with the License.
22   * You may obtain a copy of the License at
23   *
24   *      http://www.apache.org/licenses/LICENSE-2.0
25   *
26   * Unless required by applicable law or agreed to in writing, software
27   * distributed under the License is distributed on an "AS IS" BASIS,
28   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29   * See the License for the specific language governing permissions and
30   * limitations under the License.
31   */
32  package org.spf4j.concurrent.jdbc;
33  
34  import java.sql.SQLException;
35  import java.util.concurrent.TimeUnit;
36  import java.util.concurrent.TimeoutException;
37  import java.util.concurrent.locks.Condition;
38  import java.util.concurrent.locks.Lock;
39  import javax.sql.DataSource;
40  import org.spf4j.base.ExecutionContexts;
41  import org.spf4j.base.UncheckedTimeoutException;
42  import org.spf4j.concurrent.LockRuntimeException;
43  
44  /**
45   * A Jdbc Lock implementation.
46   * @author zoly
47   */
48  public final class JdbcLock implements Lock, AutoCloseable {
49  
50    private final JdbcSemaphore semaphore;
51  
52    private final int jdbcTimeoutSeconds;
53  
54    public JdbcLock(final DataSource dataSource, final SemaphoreTablesDesc semTableDesc,
55            final String lockName, final int jdbcTimeoutSeconds) throws InterruptedException, SQLException {
56      this.semaphore = new JdbcSemaphore(dataSource, semTableDesc, lockName, 1, jdbcTimeoutSeconds, true);
57      this.jdbcTimeoutSeconds = jdbcTimeoutSeconds;
58      this.semaphore.registerJmx();
59    }
60  
61    @Override
62    public void lock() {
63      try {
64          semaphore.acquire(ExecutionContexts.getMillisToDeadline(), TimeUnit.MILLISECONDS);
65      } catch (InterruptedException ex) {
66        Thread.currentThread().interrupt();
67        throw new LockRuntimeException(ex);
68      } catch (TimeoutException ex) {
69          throw new UncheckedTimeoutException(ex);
70      }
71    }
72  
73    @Override
74    public void lockInterruptibly() throws InterruptedException {
75      try {
76        semaphore.acquire(ExecutionContexts.getMillisToDeadline(), TimeUnit.MILLISECONDS);
77      } catch (TimeoutException ex) {
78        throw new UncheckedTimeoutException(ex);
79      }
80    }
81  
82    @Override
83    public boolean tryLock() {
84      try {
85        return semaphore.tryAcquire(((long) jdbcTimeoutSeconds) * 2, TimeUnit.SECONDS);
86      } catch (InterruptedException ex) {
87        Thread.currentThread().interrupt();
88        throw new LockRuntimeException(ex);
89      }
90    }
91  
92    @Override
93    public boolean tryLock(final long time, final TimeUnit unit) throws InterruptedException {
94        return semaphore.tryAcquire(time, unit);
95    }
96  
97    @Override
98    public void unlock() {
99      semaphore.release();
100   }
101 
102   @Override
103   public Condition newCondition() {
104     throw new UnsupportedOperationException();
105   }
106 
107   @Override
108   public void close() {
109     semaphore.close();
110   }
111 
112   @Override
113   public String toString() {
114     return "JdbcLock{" + "semaphore=" + semaphore + ", jdbcTimeoutSeconds=" + jdbcTimeoutSeconds + '}';
115   }
116 
117 
118 
119 }