gpt4 book ai didi

java - SQL/Java并发事务死锁

转载 作者:行者123 更新时间:2023-12-01 17:43:53 24 4
gpt4 key购买 nike

我有一个方法 boolean addIntegerColumnToDatabases(String tableName, String columnName, Connection ... conns) ,其中有 SQL 连接的集合。

对于每个 SQL 连接,我执行 schema-update-query

BEGIN
ALTER TABLE <b>tableName</b> ADD COLUMN <b>columnName</b> int4
COMMIT

由于此方法必须是 ACID,所以我喜欢并行执行此操作。

在示例中,我有两个连接(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

这是代码:

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 问题等问题,我没有 100% 的机会检查连接是否到同一数据库系统。

问题

如果执行有两个到同一数据库的连接而不执行任何架构更改,如何确保返回 false;

最佳答案

使用填充有 GUID 的帮助表 database_instance

在架构更新查询之前,获取 GUID 并将其锁定在本地字典中。

或者直接在本地锁定表,无论它位于哪个数据库:

var tablename = new object();
lock(tablename)
{
<your query>
}

关于java - SQL/Java并发事务死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60897684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com