提交 5b469189 authored 作者: m00fighter's avatar m00fighter

Trying to improve exception handling and resource closing in CreateCluster.

上级 506cb3b5
...@@ -18,6 +18,7 @@ import org.h2.util.Tool; ...@@ -18,6 +18,7 @@ import org.h2.util.Tool;
import java.io.PipedReader; import java.io.PipedReader;
import java.io.PipedWriter; import java.io.PipedWriter;
import java.io.IOException;
import java.sql.ResultSet; import java.sql.ResultSet;
/** /**
...@@ -143,8 +144,22 @@ public class CreateCluster extends Tool { ...@@ -143,8 +144,22 @@ public class CreateCluster extends Tool {
// so that data can't change while restoring the second database // so that data can't change while restoring the second database
statSource.execute("SET EXCLUSIVE 2"); statSource.execute("SET EXCLUSIVE 2");
// Pipe reader should be declared outside the try block to be visible in finally{}.
// It can be safely initialized here as it throws no exceptions.
PipedReader pipeReader = new PipedReader();
try { try {
// Pipe writer is used + closed in the inner class, in a separate thread (needs to be final).
// It should be initialized within try{} so an exception could be caught if creation fails.
// In that scenario, the the writer should be null and needs no closing,
// and the main goal is that finally{} should bring the source DB
// out of exclusive mode, and close the reader.
final PipedWriter pipeWriter = new PipedWriter(pipeReader);
// Backup data from source database in script form.
// Start writing to pipe writer in separate thread.
final ResultSet rs = statSource.executeQuery("SCRIPT");
// Delete the target database first. // Delete the target database first.
connTarget = DriverManager.getConnection( connTarget = DriverManager.getConnection(
urlTarget + ";CLUSTER=''", user, password); urlTarget + ";CLUSTER=''", user, password);
...@@ -152,29 +167,28 @@ public class CreateCluster extends Tool { ...@@ -152,29 +167,28 @@ public class CreateCluster extends Tool {
statTarget.execute("DROP ALL OBJECTS DELETE FILES"); statTarget.execute("DROP ALL OBJECTS DELETE FILES");
connTarget.close(); connTarget.close();
// Backup data from source database in script form.
// Start writing to script pipe output end in separate thread.
// Variables used from inner class must be final.
final PipedReader pipeReader = new PipedReader();
final ResultSet rs = statSource.executeQuery("SCRIPT");
new Thread( new Thread(
new Runnable(){ new Runnable(){
public void run() { public void run() {
try { try {
PipedWriter pipeWriter = new PipedWriter(pipeReader);
while (rs.next()) { while (rs.next()) {
pipeWriter.write(rs.getString(1) + "\n"); pipeWriter.write(rs.getString(1) + "\n");
} }
pipeWriter.close(); } catch (Exception eScript) {
} catch (Exception e ) { throw new IllegalStateException("Producing script from the source DB is failing.",eScript);
throw new IllegalStateException("Producing script from the source DB is failing."); } finally {
try {
pipeWriter.close();
} catch (IOException eCloseWriter) {
throw new IllegalStateException("Closing the pipe writer failed.",eCloseWriter);
}
} }
} }
} }
).start(); ).start();
// Read data from script pipe input end, restore on target. // Read data from pipe reader, restore on target.
connTarget = DriverManager.getConnection(urlTarget, user, password); connTarget = DriverManager.getConnection(urlTarget, user, password);
RunScript runScript = new RunScript(); RunScript runScript = new RunScript();
runScript.setOut(out); runScript.setOut(out);
...@@ -184,10 +198,19 @@ public class CreateCluster extends Tool { ...@@ -184,10 +198,19 @@ public class CreateCluster extends Tool {
// set the cluster to the serverList on both databases // set the cluster to the serverList on both databases
statSource.executeUpdate("SET CLUSTER '" + serverList + "'"); statSource.executeUpdate("SET CLUSTER '" + serverList + "'");
statTarget.executeUpdate("SET CLUSTER '" + serverList + "'"); statTarget.executeUpdate("SET CLUSTER '" + serverList + "'");
} catch (IOException eAttach) {
throw new IllegalStateException("Failed attaching pipe writer to pipe reader.",eAttach);
} finally { } finally {
// switch back to the regular mode // switch back to the regular mode
statSource.execute("SET EXCLUSIVE FALSE"); statSource.execute("SET EXCLUSIVE FALSE");
try {
pipeReader.close();
} catch (Exception eCloseReader) {
throw new IllegalStateException("Failed closing the pipe reader.",eCloseReader);
}
} }
} finally { } finally {
JdbcUtils.closeSilently(statSource); JdbcUtils.closeSilently(statSource);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论