Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法在Postgres/JDBC中跨层隔离事务_Java_Sql_Postgresql_Jdbc - Fatal编程技术网

Java 无法在Postgres/JDBC中跨层隔离事务

Java 无法在Postgres/JDBC中跨层隔离事务,java,sql,postgresql,jdbc,Java,Sql,Postgresql,Jdbc,我正在开发一个Java项目,它使用JDBC集成了一个Postgressql9.0数据库层。SQL封装在函数中,在Java中执行,类似于使用JDBC的存储过程 数据库需要一个标头详细方案,其中详细记录需要标头的外键ID。因此,首先写入标题行,然后写入数千条详细记录。我需要阻止用户访问标题,直到详细信息完成写入 您可以建议包装整个事务,以便在细节记录完成写入之前无法提交标题记录。但是,您可以在下面看到,我已将事务隔离到Java中的调用:写入标头,然后循环通过详细信息(同时写入详细信息行)。由于数据的

我正在开发一个Java项目,它使用JDBC集成了一个Postgressql9.0数据库层。SQL封装在函数中,在Java中执行,类似于使用JDBC的存储过程

数据库需要一个标头详细方案,其中详细记录需要标头的外键ID。因此,首先写入标题行,然后写入数千条详细记录。我需要阻止用户访问标题,直到详细信息完成写入

您可以建议包装整个事务,以便在细节记录完成写入之前无法提交标题记录。但是,您可以在下面看到,我已将事务隔离到Java中的调用:写入标头,然后循环通过详细信息(同时写入详细信息行)。由于数据的庞大,将详细数据传递给函数以执行一个事务是不可行的

我的问题是:如何在JDBC级别包装事务,以便在细节记录完成写入之前不提交头?

最好的解决方案比喻是SQL Server的命名事务,其中事务可以在数据访问层代码中启动(在其他事务之外),并在稍后的DB调用中完成

以下(简化)代码执行时不会出错,但无法解决隔离问题:

DatabaseManager mgr = DatabaseManager.getInstance();
Connection conn = mgr.getConnection();
CallableStatement proc = null;

conn.setAutoCommit(false);
proc = conn.prepareCall("BEGIN TRANSACTION");
proc.execute();

//Write header details
writeHeader(....);
for(Fault fault : faultList) {
    writeFault(fault, buno, rsmTime, dnld, faultType, verbose);
}
proc = conn.prepareCall("COMMIT TRANSACTION");
proc.execute();

您的精彩回答将不胜感激

您是否对writeHeader和WriteDefault使用相同的连接

conn.setAutoCommit(false);

headerProc = conn.prepareCall("headerProc...");
headerProc.setString(...);
headerProc.execute();

detailProc = conn.prepareCall("detailProc...");

for(Fault fault : faultList) {
    detailProc.setString(...);
    detailProc.execute();
    detailProc.clearParameters();
}

conn.commit();

然后,您应该查看“addBatch”中的详细循环。

您是否对writeHeader和writeFault使用相同的连接

conn.setAutoCommit(false);

headerProc = conn.prepareCall("headerProc...");
headerProc.setString(...);
headerProc.execute();

detailProc = conn.prepareCall("detailProc...");

for(Fault fault : faultList) {
    detailProc.setString(...);
    detailProc.execute();
    detailProc.clearParameters();
}

conn.commit();

然后,您应该查看“addBatch”中的详细循环。

虽然您似乎已经解决了眼前的问题,但如果您在JavaEE容器中运行,您可能需要查看JTA。根据我的经验,JTA与EJB3.1*相结合,可以让您进行声明性事务控制,并大大简化事务管理


*别担心,EJB3.1比以前的EJB规范更简单、更干净,也不那么可怕。

虽然您似乎已经解决了眼前的问题,但如果您在javaee容器中运行,您可能需要研究JTA。根据我的经验,JTA与EJB3.1*相结合,可以让您进行声明性事务控制,并大大简化事务管理


*别担心,EJB3.1比以前的EJB规范更简单、更干净,也不那么可怕。

关于
DatabaseManager
呢?为什么不在
writeHeader
writeFault
循环上共享连接(和事务)?我看不到你的代码有任何没有解决隔离问题的地方。问题出在哪里?对不起,伙计们,我有一个隐藏的conn.setAutoCommit(true);问题解决了!感谢您的关注。
DatabaseManager
怎么样?为什么不在
writeHeader
writeFault
循环上共享连接(和事务)?我看不到任何关于您的代码不能解决隔离问题的信息。问题出在哪里?对不起,伙计们,我有一个隐藏的conn.setAutoCommit(true);问题解决了!谢谢你的关注。谢谢你的回答,格伦。虽然我发现我的错误是一个隐藏的自动提交,但你的答案将是我下一步要尝试的。谢谢你的回答,格伦。虽然我确实发现我的错误是一个隐藏的自动提交,但你的答案将是我下一步要尝试的。谢谢,克雷格,我会的。听起来JTA事务比其他事务API更受推荐。谢谢,克雷格,我会的。听起来JTA事务比其他事务API更受推荐。