Daniel John Debrunner wrote:

Technically I think auto-commit mode is at the statement level. Section
10.1 of JDBC 3.0 documents auto-commit mode in terms of statements, not
ResultSet objects. But a query statement produces a ResultSet and
actions on such ResultSets (not all ResultSets) affect the auto-commit
logic. However Derby uses the same implementation for all ResultSet's,
thus some flag to change behaviour is required.

Actually my current line of thought leads me to believe I should be evaluating commits at the Connection level. Whenever any Statement commits for whatever reason a commit is made at the connection level that affects all other statements. For example the following piece of code will throw an exception (for embedded):
Statement s1 = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
ResultSet rs1 = s1.executeQuery("select * from " + tablename);
Statement s2 = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
ResultSet rs2 = s2.executeQuery("select * from " + tablename + " where num = 1");
rs1.next();

because the execute of Statement s2 causes a commit which in turn causes rs1 to 
close as per the CLOSE_CURSORS_AT_COMMIT value.

I think it's implied from 10.1, auto-commit only applies to the
*> ***statements** listed there, thus ResultSet's from DatabaseMetaData have
nothing to do with auto-commit.

Excellent, good to hear another opinion. This being the case we have another 
thing that needs to be fixed on the Client. The following code will throw an 
Exception using the Derby client:

Statement s1 = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

ResultSet rs1 = s1.executeQuery("select * from " + tablename);

DatabaseMetaData dbmd = conn.getMetaData();

ResultSet rs2 = dbmd.getCatalogs();


/*
Interestingly a call to rs1.next() here would not throw an exception because 
the call from the Server is recognized as a MetaDatabase Statement call.

*/

while (rs2.next());
/*

When the ResultSet finishes the client will initiate an autocommit that 
bypasses the forMetaData logic, closing rs1.

*/

rs1.next()

This might warrant another DERBY-213 subtask but I would like to hear that 
opinion confirmed before I create it.

Philip

Reply via email to