Tuple concurrently updated when granting permissions
14:15 08 Feb 2023

Struggling with database queries - not a db expert by any means, any help would be appreciated.

When dynamically created databases and schemas, once in awhile I get this error:

Unable to apply database grants.
io.vertx.core.impl.NoStackTraceThrowable: Error granting permission.
io.vertx.pgclient.PgException:
ERROR: tuple concurrently updated (XX000)

The role names, database names and schema names are replaced in the query strings in a separate place, i modified the code to pass in the query string directly to the transaction for simplicity.

The permissions being granted are as follows:

private static final String ERR_PERMISSION_GRANT_ERROR_MESSAGE = "Error granting permission. ";
private static final String ADVISORY_LOCK = "SELECT pg_try_advisory_lock("
        + String.valueOf(BigInteger.valueOf(Double.valueOf(Math.random()).longValue())) + ")";  
private static final String CREATE_USER = "CREATE ROLE  LOGIN PASSWORD ;";
private static final String GRANT_PERMISSION1 = "GRANT CREATE, CONNECT ON DATABASE  TO ;";
private static final String GRANT_PERMISSION2 = "GRANT USAGE ON SCHEMA  TO ;";
private static final String GRANT_PERMISSION3 = "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA  TO ";
private static final String GRANT_PERMISSION5 = "ALTER DEFAULT PRIVILEGES IN SCHEMA  GRANT ALL ON SEQUENCES TO ;";


private static Promise grantDatabase(PgPool pool, String databaseName, String userName, String schemaName,
        Vertx vertx) {
    Promise promise = Promise.promise();

    pool.getConnection()
            // Transaction must use a connection
            .onSuccess(conn -> {
                // Begin the transaction
                conn.begin().compose(tx -> conn
                        // Various statements
                        .query(updateQueryString(ADVISORY_LOCK, databaseName, userName)).execute()
                        .compose(
                                res1 -> conn.query(
                                        updateQueryString(GRANT_PERMISSION1 databaseName, userName))
                                        .execute()
                                        .compose(res2 -> conn.query(
                                                updateQueryString(GRANT_PERMISSION2, schemaName, userName))
                                                .execute()
                                                .compose(res3 -> conn
                                                        .query(updateQueryString(
                                                                GRANT_PERMISSION3, schemaName, userName))
                                                        .execute()
                                                        .compose(res4 -> conn
                                                                .query(updateQueryString(GRANT_PERMISSION5,
                                                                        schemaName, userName))
                                                                .execute()))))
                        // Commit the transaction
                        .compose(res5 -> tx.commit()))
                        // Return the connection to the pool
                        .eventually(v -> conn.close()).onSuccess(v -> promise.complete(Boolean.TRUE))
                        .onFailure(err -> promise
                                .fail(ERR_PERMISSION_GRANT_ERROR_MESSAGE
            });
    return promise;
}

How do I fix the tuple concurrently updated error in this case? I only have a single instance of my service running.

PostgreSQL v14.6 (Homebrew) vertx-pg-client 4.3.8

sql postgresql vert.x