I have a method boolean addIntegerColumnToDatabases(String tableName, String columnName, Connection ... conns)
where I have a collection of SQL-Connections.
For every SQL-Connection I execute the schema-update-query
BEGIN
ALTER TABLE <b>tableName</b> ADD COLUMN <b>columnName</b> int4
COMMIT
Since this method must be ACID I like to do this in parallel.
In example I have two connections (C1, C2):
C1: BEGIN
C2: BEGIN
C1: ALTER TABLE tableName ADD COLUMN columnName int4
C2: ALTER TABLE tableName ADD COLUMN columnName int4
C1: COMMIT
C2: COMMIT
This is the code:
Statement[] s = new Statement[conns.length];
int i =0;
for(Connection c:conns) {
c.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
c.setAutoCommit(false);
s[i++]=c.createStatement();
}
for(Statement st:s) {
st.executeUpdate("ALTER TABLE "+tableName+" ADD COLUMN "+columnName+" int4;");
}
for(Connection c:conns) {
c.commit();
}
return true;
This works as long as the connections are on different databases.
Problem
If C1 and C2 are connected to the same database C2 waits for the C1 to be committed on Postgres-Side and C1 waits for C2 on Java-Side. Voila we have a deadlock.
I have no 100% chance to check if the connections are to the same database system because of issues like clustering/balancing, ipv4/6 and dns-issues.
Question
How to make sure to return false;
if execution having two connections to the same database without executing any schema-change?