SQL / Java并发事务死锁

问题描述 投票:0回答:1

我有一个方法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;,如果执行具有到同一数据库的两个连接而没有执行任何模式更改?

java sql transactions deadlock
1个回答
0
投票

使用填充有GUID的帮助表database_instance。>>

在执行模式更新查询之前,获取GUID并将其锁定在本地字典中。

© www.soinside.com 2019 - 2024. All rights reserved.