我有一个方法boolean addIntegerColumnToDatabases(String tableName, String columnName, Connection ... conns)
,其中有一个SQL连接集合。
对于我执行的每个SQL连接,执行schema-update-query
BEGIN
ALTER TABLE tableName添加列columnName int4
COMMIT
由于此方法必须是ACID,所以我希望在paralell中执行此操作。
例如,我有两个连接(C1,C2):
C1:开始
C2:开始
C1:ALTER TABLE tableName添加列columnName int4
C2:ALTER TABLE tableName添加列columnName int4
C1:COMMIT
C2:提交
这是代码:
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等待在Postgres端提交C1,而C1等待Java端上的C2。瞧,我们陷入僵局。
由于集群/平衡,ipv4 / 6和dns-issues之类的问题,我没有100%的机会检查连接是否连接到同一数据库系统。
如何确保return false;
,如果执行具有到同一数据库的两个连接而没有执行任何模式更改?
使用填充有GUID的帮助表database_instance
。>>
在执行模式更新查询之前,获取GUID并将其锁定在本地字典中。