class AbstractLockBasedProxyManager<K> extends AbstractProxyManager<K> {

    protected AbstractLockBasedProxyManager(ClientSideConfig clientSideConfig) {
        super(injectTimeClock(clientSideConfig));
    }

    @Override
    public <T> CommandResult<T> execute(K key, Request<T> request) {
        Timeout timeout = Timeout.of(getClientSideConfig());
        LockBasedTransaction transaction = timeout.call(requestTimeout -> allocateTransaction(key, requestTimeout));
        try {
            return execute(request, transaction, timeout);
        } finally {
            transaction.release();
        }
    }

    @Override
    public boolean isAsyncModeSupported() {
        return false;
    }

    @Override
    public <T> CompletableFuture<CommandResult<T>> executeAsync(K key, Request<T> request) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected CompletableFuture<Void> removeAsync(Object key) {
        return null;
    }

    protected abstract LockBasedTransaction allocateTransaction(K key, Optional<Long> timeoutNanos);

    private <T> CommandResult<T> execute(Request<T> request, LockBasedTransaction transaction, Timeout timeout) {<FILL_FUNCTION_BODY>}

    private void unlockAndRollback(LockBasedTransaction transaction) {
        try {
            transaction.unlock();
        } finally {
            transaction.rollback();
        }
    }

    private static ClientSideConfig injectTimeClock(ClientSideConfig clientSideConfig) {
        if (clientSideConfig.getClientSideClock().isPresent()) {
            return clientSideConfig;
        }
        return clientSideConfig.withClientClock(TimeMeter.SYSTEM_MILLISECONDS);
    }

    protected void applyTimeout(PreparedStatement statement, Optional<Long> requestTimeoutNanos) throws SQLException {
        if (requestTimeoutNanos.isPresent()) {
            int timeoutSeconds = (int) Math.max(1, TimeUnit.NANOSECONDS.toSeconds(requestTimeoutNanos.get()));
            statement.setQueryTimeout(timeoutSeconds);
        }
    }

}

        RemoteCommand<T> command = request.getCommand();
        timeout.run(transaction::begin);

        // lock and get data
        byte[] persistedDataOnBeginOfTransaction;
        try {
            persistedDataOnBeginOfTransaction = timeout.call(transaction::lockAndGet);
        } catch (Throwable t) {
            unlockAndRollback(transaction);
            throw BucketExceptions.from(t);
        }

        // check that command is able to provide initial state in case of bucket does not exist
        if (persistedDataOnBeginOfTransaction == null && !request.getCommand().isInitializationCommand()) {
            unlockAndRollback(transaction);
            return CommandResult.bucketNotFound();
        }

        try {
            MutableBucketEntry entry = new MutableBucketEntry(persistedDataOnBeginOfTransaction);
            CommandResult<T> result = command.execute(entry, super.getClientSideTime());
            if (entry.isStateModified()) {
                byte[] bytes = entry.getStateBytes(request.getBackwardCompatibilityVersion());
                if (persistedDataOnBeginOfTransaction == null) {
                    timeout.run(requestTimeout -> transaction.create(bytes, entry.get(), requestTimeout));
                } else {
                    timeout.run(requestTimeout -> transaction.update(bytes, entry.get(), requestTimeout));
                }
            }
            transaction.unlock();
            timeout.run(transaction::commit);
            return result;
        } catch (Throwable t) {
            unlockAndRollback(transaction);
            throw BucketExceptions.from(t);
        }
    
<methods>public AsyncProxyManager<K> asAsync() ,public RemoteBucketBuilder<K> builder() ,public Optional<io.github.bucket4j.BucketConfiguration> getProxyConfiguration(K) <variables>private static final io.github.bucket4j.distributed.proxy.RecoveryStrategy DEFAULT_RECOVERY_STRATEGY,private static final io.github.bucket4j.distributed.proxy.optimization.Optimization DEFAULT_REQUEST_OPTIMIZER,private AsyncProxyManager<K> asyncView,private final non-sealed io.github.bucket4j.distributed.proxy.ClientSideConfig clientSideConfig