Hi,

(1) add a manual command to clean them up
>>
>
Yes, that would be an option, and we would not have to change behavior by
default (which is a risk as it could break existing applications).


> (2) change it so that the client can only read from a BLOB while a
>> transaction is open. Flush any temporary BLOBs on commit. This is how other
>> databases work, but it would be a change for us. So maybe we would have to
>> hide this option behind a flag for now.
>>
>
I didn't know that. I made some tests (see below), and at least Apache
Derby seems to do that. I'm not sure about other databases however;
PostgreSQL doesn't seem to support CLOB(?) and HSQLDB didn't remove the
CLOB on commit. That should be possible to implement; we already have an
array for LOB entries to remove on commit, in Session.unlinkLobMap. I think
adding the LOBs there should work. Yes, we need to be a bit careful with
compatibility (with other database and with previous versions of H2); I
guess we could change the default behavior in version 1.4.x as it is marked
beta.

Test case results:

jdbc:h2:mem:
while reading: aaa
after next: aaa
after result set close: aaa
after delete: aaa

jdbc:hsqldb:/tmp/db/test
while reading: aaa
after next: aaa
after result set close: aaa
after delete: aaa

jdbc:derby:/tmp/db/test2;create=true
while reading: aaa
after next: aaa
after result set close: java.sql.SQLException: You cannot invoke other
java.sql.Clob/java.sql.Blob methods after calling the free() method or
after the Blob/Clob's transaction has been committed or rolled back.
after delete: java.sql.SQLException: You cannot invoke other
java.sql.Clob/java.sql.Blob methods after calling the free() method or
after the Blob/Clob's transaction has been committed or rolled back.

Test case:


package db;

import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.h2.tools.DeleteDbFiles;

public class TestMultiDb {

    public static void main(String[] a) throws Exception {
        DeleteDbFiles.execute("~/temp", "test", true);
//        Server s = Server.createTcpServer().start();
//        try {
//            test("org.h2.Driver", "jdbc:h2:tcp://localhost/~/temp/test",
"sa", "sa");
//        } finally {
//            s.stop();
//        }
        test("org.h2.Driver", "jdbc:h2:mem:", "sa", "sa");
        // test("org.h2.Driver", "jdbc:h2:~/temp/test", "sa", "sa");
        test("org.hsqldb.jdbcDriver", "jdbc:hsqldb:/tmp/db/test", "sa",
"sa");
        test("org.apache.derby.jdbc.EmbeddedDriver",
"jdbc:derby:/tmp/db/test2;create=true", "sa", "sa");
        // test("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/test", "sa", "sa");
        // test("oracle.jdbc.driver.OracleDriver",
        // "jdbc:oracle:thin:@192.168.0.100:1521:XE", "sa", "sa");
        // test("org.postgresql.Driver", "jdbc:postgresql:test", "sa",
"sa");
    }

    static void test(String driver, String url, String user, String
password) throws Exception {
        System.out.println(url);
        Class.forName(driver);

        Connection conn = DriverManager.getConnection(url, user, password);
        Statement stat =
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
        try {
            stat.execute("drop table test");
        } catch (SQLException e) {
            // ignore
        }
        try {
            stat.execute("create table test(id int primary key, data
clob)");
        } catch (SQLException e) {
            stat.execute("create table test(id int primary key, data
varchar(255))");
        }
        PreparedStatement prep = conn.prepareStatement("insert into test
values(?, ?)");
        prep.setInt(1, 1);
        prep.setString(2, "aaa" + new String(new char[1024 *
16]).replace((char) 0, 'x'));
        prep.execute();
        prep.setInt(1, 2);
        prep.setString(2, "bbb" + new String(new char[1024 *
16]).replace((char) 0, 'x'));
        prep.execute();
        ResultSet rs = stat.executeQuery("select * from test order by id");
        rs.next();
        Clob c1 = rs.getClob(2);
        System.out.println("while reading: " + c1.getSubString(1, 3));
        rs.next();
        System.out.println("after next: " + c1.getSubString(1, 3));
        rs.close();
        try {
            System.out.println("after result set close: " +
c1.getSubString(1, 3));
        } catch (SQLException e) {
            System.out.println("after result set close: " + e);
        }
        stat.execute("delete from test");
        try {
            System.out.println("after delete: " + c1.getSubString(1, 3));
        } catch (SQLException e) {
            System.out.println("after delete: " + e);
        }
        conn.close();
        System.out.println();
    }

}

Regards,
Thomas

-- 
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 http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.

Reply via email to