У меня есть метод boolean addIntegerColumnToDatabases(String tableName, String columnName, Connection ... conns)
, где у меня есть коллекция SQL -Connections.
Для каждого SQL -Connection я выполняю запрос на обновление схемы
BEGIN
ALTER TABLE <b>tableName</b> ADD COLUMN <b>columnName</b> int4
COMMIT
Поскольку этот метод должен быть ACID, мне нравится делать это параллельно.
Например, у меня есть два соединения (C1, C2):
C1: НАЧАЛО
C2: НАЧАЛО
C1: ALTER TABLE tableName ADD COLUMN columnName int4
C2: ALTER TABLE tableName ADD COLUMN columnName int4
C1 : COMMIT
C2: COMMIT
Это код:
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;
Это работает, если соединения находятся в разных базах данных.
Проблема
Если C1 и C2 подключены к одной базе данных, C2 ожидает фиксации C1 на Postgres -Side, а C1 ждет C2 на Java -Side. Вуаля, у нас тупик.
У меня нет 100% шанса проверить, подключены ли к одной и той же системе базы данных из-за таких проблем, как кластеризация / балансировка, ipv4 / 6 и dns-проблемы.
Вопрос
Как удостовериться в return false;
, если выполнение имеет два соединения с одной и той же базой данных без выполнения какого-либо изменения схемы?