All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.eventsourcing.postgresql.PostgreSQLLockProvider Maven / Gradle / Ivy

There is a newer version: 0.4.6
Show newest version
/**
 * Copyright (c) 2016, All Contributors (see CONTRIBUTORS file)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package com.eventsourcing.postgresql;

import com.eventsourcing.Lock;
import com.eventsourcing.LockProvider;
import com.google.common.util.concurrent.AbstractService;
import lombok.Getter;
import lombok.SneakyThrows;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * Implementation of {@link LockProvider} that uses PostgreSQL's
 * explicit locking
 * functionality
 */
@Component(property = {"type=PostgreSQLLockProvider"})
public class PostgreSQLLockProvider extends AbstractService implements LockProvider {

    @Reference
    protected DataSourceProvider dataSourceProvider;

    private DataSource dataSource;

    @Activate
    protected void activate() {
        dataSource = dataSourceProvider.getDataSource();
    }

    public PostgreSQLLockProvider() {}

    @Override protected void doStart() {
        notifyStarted();
    }

    @Override protected void doStop() {
        notifyStopped();
    }

    public PostgreSQLLockProvider(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @SneakyThrows
    @Override public Lock lock(Object lock) {
        return new PostgreSQLLock(dataSource.getConnection(), lock.hashCode());
    }

    public class PostgreSQLLock implements Lock {

        private final Connection connection;
        private final long key;

        @Getter
        private boolean locked;

        public PostgreSQLLock(Connection connection, long key) throws SQLException {
            this.connection = connection;
            this.key = key;
            this.locked = true;
            try (PreparedStatement s = connection.prepareStatement("SELECT pg_advisory_lock(?)")) {
                s.setLong(1, key);
                s.execute();
            }
        }

        @SneakyThrows
        @Override public void unlock() {
            try (PreparedStatement s = connection.prepareStatement("SELECT pg_advisory_unlock(?)")) {
                s.setLong(1, key);
                s.execute();
            }
            connection.close();
            locked = false;
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy