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