This content has been marked as final. Show 2 replies
Using: JBoss 4.0.2, Hibernate 3.0.5, jTDS.
I am getting connections via a JBoss data source (no-tx-datasource).
I am handling transactions manually. If my code throws an exception, I am calling Connection.rollback in the catch.
In the code that catches the exception and calls rollback, I don't know whether any work has been done (i.e., anything to roll back).
org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection wraps the connection created by the JDBC driver. It maintains its own autocommit value (jdbcAutoCommit), separate from the one held in the driver. BaseWrapperManagedConnection.jdbcAutoCommit is propagated to the driver only in certain circumstances -- rolling back isn't one of them. Generally, it's when actual work is being done.
The problem arises when rollback is called before jdbcAutoCommit is propagated to the driver. The driver still has autocommit=true, and throws an exception when the rollback call is propagated to it.
Thus, the following code will fail:
DataSource ds = getDataSource();
Connection con = ds.getConnection();
con.setAutoCommit(false); // not propagated to driver
con.rollback(); // driver throws an exception because autocommit is true.
Of course, my code doesn't look quite like this. The rollback is attempted in a catch block, where I don't know whether or not any work has been done.
Does anyone know what the thinking behind this behavior is? Or, better yet, suggest a clean way of avoiding my problem?