【发布时间】:2015-03-02 23:42:39
【问题描述】:
在 PostgreSQL 中,我面临竞争条件。我的表和模式可能会被系统中的单独进程删除。使用成语如果模式和表存在,则读取内容因此通常不起作用,因为表可能在语句中间不再存在。
我不明白为什么SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 没有帮助。我想我可能期望在我的事务期间模式和表的视图保持一致,但我没有。以下是我的 Java 代码:
pgConnection = DriverManager.getConnection(/* ... */);
pgConnection.setAutoCommit(false);
PreparedStatement statement = pgConnection.prepareStatement(
"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;");
statement.execute();
statement = pgConnection.prepareStatement(
"SELECT ('myschema','config') IN " +
"(SELECT table_schema,table_name FROM information_schema.tables);");
ResultSet result = statement.executeQuery();
result.next();
if(result.getBoolean(1)) {
statement = pgConnection.prepareStatement("SELECT key,value FROM myschema.config;");
result = statement.executeQuery(); // here I'm often getting an exception
/* ... */
}
我得到的例外是:
org.postgresql.util.PSQLException: ERROR: relation "myschema.config" does not exist
这怎么可能?我认为ISOLATION LEVEL SERIALIZABLE 会保护我免受这种情况的影响。那是因为删除模式是太具体的操作而无法保持隔离吗?还是我做错了什么?
【问题讨论】:
-
并非所有数据库都将 DDL 视为“在”事务中。 (我不确定pg的立场是什么。)
标签: java postgresql transactions race-condition