So, if you set DB_CLOSE_ON_EXIT=FALSE and use a connection pool, but don't 
dispose() of it (e.g. by terminating your program with Ctrl-C), you'll 
reliably encounter this problem. Just closing your connections is no use, 
because the pool doesn't close the real connections underneath.

Even if you don't set that param and don't use a connection pool, you can 
still run into the problem. Open a raw connection that you never close. 
Open another raw connection, commit some data, then close this connection. 
Then SIGKILL yourself so that the first connection never gets closed. 
You'll find that the committed data isn't available on restart. (A tiny 
delay just before the SIGKILL might fix the problem, so to demonstrate the 
problem, don't delay.)
The short program attached demonstrates this problem.

----
References: http://h2database.com/html/faq.html#reliable
"Some users have reported that after a power failure, the database cannot 
be opened sometimes. In this case, use a backup of the database or the 
Recover tool. Please report such problems. The plan is that the database 
automatically recovers in all situations."

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.
import java.io.*;
import java.sql.*;

/** If you run this program twice in a row against an empty database directory,
 *  you would expect the second run to fail to create table T1, because the
 *  first run had created it. But the second run also successfully creates T1,
 *  showing that H2 Database did not durably persist the first run's
 *  transaction when that autocommitted. h2-1.4.197 . */
public class H2Durability {
  private static final String DB_PATH = "~/h2durability_tmpdb4029";

  public static void main(String[] args) throws Exception {
    Connection wontClose = createConn();

    Connection c = createConn();
    Statement st = c.createStatement();
    try {
      st.executeUpdate("CREATE TABLE T1(id integer)");
      st.close();
      c.close();
      System.out.println("T1 created");
    } catch (SQLException e) {
      System.out.println(e.getMessage());
    }
    killSelf();
  }

  static void killSelf() throws Exception {
    Runtime.getRuntime()
    .exec(String.format("/bin/kill -KILL %d", ProcessHandle.current().pid()))
    .waitFor();
  }

  static Connection createConn() throws SQLException {
    return DriverManager.getConnection(url(), "", "");
  }

  static String url() {
    return String.format("jdbc:h2:%s", DB_PATH);
  }
}

Reply via email to