Java PostgreSQL信息\u schema.tables和事务隔离级别
在PostgreSQL中,我面临着比赛条件。我的表和架构可能会被系统中的单独进程删除。如果模式和表存在,则使用习语,因此读取内容通常不起作用,因为表可能在语句的中间不存在。 有一件事我不明白,为什么设置事务隔离级别SERIALIZABLE没有帮助。我想我可能期望在事务期间模式和表的视图是一致的,但我没有。下面是我的Java代码:Java PostgreSQL信息\u schema.tables和事务隔离级别,java,postgresql,transactions,race-condition,Java,Postgresql,Transactions,Race Condition,在PostgreSQL中,我面临着比赛条件。我的表和架构可能会被系统中的单独进程删除。如果模式和表存在,则使用习语,因此读取内容通常不起作用,因为表可能在语句的中间不存在。 有一件事我不明白,为什么设置事务隔离级别SERIALIZABLE没有帮助。我想我可能期望在事务期间模式和表的视图是一致的,但我没有。下面是我的Java代码: pgConnection = DriverManager.getConnection(/* ... */); pgConnection.setAutoCommit(fa
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
这怎么可能?我认为隔离级别SERIALIZABLE可以保护我不受这种情况的影响。这是因为删除模式是一种过于特定的操作,无法保持隔离吗?还是我做了一些根本错误的事情?SQL语句设置了事务隔离级别。不启动事务。不管怎么说,你不感兴趣
按照您的代码,您可以这样编写SQL语句
set transaction isolation level serializable;
begin transaction;
...
或者像这样
begin transaction isolation level serializable;
...
但是,您不需要为此使用可序列化事务。您可以通过在两个终端会话中运行psql进行测试
sandbox=# begin transaction;
BEGIN
sandbox=# begin transaction;
BEGIN
sandbox=# select * from foo for update;
foo_id
--------
1
(1 row)
sandbox=# drop table foo;
[waits . . .]
sandbox=# update foo set foo_id = 2;
UPDATE 1
sandbox=# select * from foo;
foo_id
--------
2
(1 row)
sandbox=# commit;
COMMIT
DROP TABLE
sandbox=# commit;
COMMIT
sandbox=# select * from foo;
ERROR: relation "foo" does not exist
LINE 1: select * from foo;
话虽如此,设计一个数据库,其中的表和模式可能会定期被删除,我认为创建似乎是一个坏主意并非所有数据库都认为DDL在事务中。我不确定pg的立场是什么。我看到运行两个相互冲突的转换会导致冻结其中一个,以避免不一致。。现在我也看到了psql事务是如何工作的——它们相互阻塞而不是冲突。。是这样吗?我做了类似的实验,插入了违反约束的双重性,看起来是的,基本上是对的。每个事务都可以设置自己的事务。每个事务的隔离级别告诉PostgreSQL它可以容忍其他并发事务的影响。在英语中,等待可能比冻结更好;在英语中,冰冻意味着寒冷,但等待并不意味着寒冷。