Most Java code uses autocommit=false. The only exception I ever saw was executing interactively-entered SQL, and in that case, you wouldn't want to pass the Connection to Ebean anyway.
And I wouldn't worry about server roundtrips. Optimization "just in case" is the root of all evil :-)
In this case, there are already two layers that could optimize that out: the connection pool (if it hands out wrappers around the actual Connection objects), and the JDBC driver where the optimization is really easy - just delay submitting a changed autocommit setting until the next transactional SQL statement is sent.
I'd reconsider only if concrete TCP-level logging shows that autocommit does, in fact, cause server roundtrips in relevant JDBC drivers.
I don't think this is sufficient.
I need to think more about the issue above. If there was a scenario where autoCommit=true really rocked in terms of performance then that would be worth looking at in terms of changing JdbcTransaction.
The 4 options I see are:
2 - Turn autoCommit=true off for the duration of any non-query-only transaction (Your original suggestion I think, we also reset autoCommit after commit/rollback as we can't assume the use of the Ebean pool which otherwise does this for us)
autocommit =true can never safely be used in any write transaction
The difference is in what happens after the commit.
Do you set autocommit to true after the commit? Then you might inadvertently switch the caller's setting. Not an issue if all your code is always in your by-default-true-autocommit scenario, but you don't want to wrap that code in a library and reuse in another project that has a different autocommit policy.
Do you reset autocommit to the original state after the commit? Then the autocommit setting will be correct, but the JDBC driver might issue an implicit commit even if you set autocommit from false to false (the Javadoc on setAutoCommit says "calling this will cause a commit", not "calling this will cause a commit if it actually changes the autocommit setting").
Transactional code that needs to be reusable regardless of outside autocommit settings hence probably needs to look like this:
boolean inAutocommit = conn.autoCommit ();
if (inAutocommit) {
conn.setAutoCommit (false);
}
... I/U/D code ...
if (inAutocommit) {
conn.setAutoCommit (true);
}
I consider that kind of code "bad poetry", but it does the job.
YMMV.
Hi,
I have committed the change to JdbcTransaction. It turns off autoCommit for the duration of the transaction and then turn's it back on prior to putting the connection back into the pool.
ie. Option 2.
Daryl, it would be great if you can test this against you use cases if you get a chance - thanks.
Hi,
I have committed the change to JdbcTransaction. It turns off autoCommit for the duration of the transaction and then turn's it back on prior to putting the connection back into the pool.
Daryl, it would be great if you can test this against you use cases if you get a chance - thanks.
Daryl, it would be great if you can test this against you use cases if you get a chance - thanks.
I tested 2.7.5 with my unit test on this issue and it passed.
if (connection!=null) {this.autoCommit = connection.getAutoCommit();if (this.autoCommit) {connection.setAutoCommit(false);}}
this.autoCommit = connection.getAutoCommit();if (connection.getAutoCommit()) {connection.setAutoCommit(false);}