Unexpected Transaction Behavior
Its been a while since I've had the pleasure of doing serious work in Java, but I'm seeing something odd, and not sure how to work around it.
I'm using:
Oracle 10 Express
Websphere Community Ed
Oracle 10 thin drivers
I've got a routine inserting into a table. There is a trigger and a sequence used to generate an autoincrement field for the table's primary key.
The code performs an insert into a table, then tries to fetch back the current value of the sequence in order to return it to the caller.
CREATE_NEW_MENU_ITEM = "INSERT INTO MENUITEMS (TITLE,PARENTID,URL,ENABLED) values (?,?,?,?)";
GET_LAST_INSERTED_MENU_ID = "XSELECT MENUITEM_ID_SEQ.CURRVAL from DUAL";
try {
conn = DatabaseConnector.getConnection();
conn.setAutoCommit(false);
pstmt = conn.prepareStatement(CREATE_NEW_MENU_ITEM);
pstmt.setString(1, item.getItemTitle());
pstmt.setInt(2, item.getParentID());
pstmt.setString(3, item.getURL());
pstmt.setString(4, item.getEnabled());
pstmt.executeUpdate();
pstmt2 = conn.prepareStatement(GET_LAST_INSERTED_MENU_ID);
rs = pstmt2.executeQuery();
rs.next();
uniqueId = rs.getInt(1);
conn.commit();
} catch (SQLException e) {
conn.rollback();
throw e;
}
I purposefully typo'ed GET_LAST_INSERTED_MENU_ID in order to throw an SQLException, which it does.
However, I find that the insert statement CREATE_NEW_MENU_ITEM still ends up being committed.
Help? What am I missing?
[1569 byte] By [
mgrommeta] at [2007-11-27 8:40:36]

# 3
Here is a link showing code on how to get the newly generated key.
It uses a Statement, but you should be able to use the same code with a PreparedStatement. (substitute PreparedStatement for Statement):
http://developers.sun.com/docs/javadb/10.2.2/ref/crefjavstateautogen.html
I suspect because you are using another preparedStatement to get a generated key that hasn't yet been committed, java commits it in order to return the key. Something odd like that. I personnally wouldn't spend too much time worrying about this odd behavior and just code per the link provided.
I know the example code you provided is just a fragment is probably not complete, but here's a slightly cleaned up version of it for your own use of closing connection, finally block, dealing with autoCommit, etc.
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
conn = DatabaseConnector.getConnection();
conn.setAutoCommit(false);
pstmt = conn.prepareStatement(CREATE_NEW_MENU_ITEM);
pstmt..clearParameters();
pstmt.setString(1, item.getItemTitle());
pstmt.setInt(2, item.getParentID());
pstmt.setString(3, item.getURL());
pstmt.setString(4, item.getEnabled());
pstmt.executeUpdate();
conn.commit();
} catch (SQLException e) {
conn.rollback();
throw e;
} finally {
if(conn!=null)
conn.setAutoCommit(true);// must ensure this occurs even if the
// remaiing functions fail
if(rs!=null)
rs.close();
if(pstmt !=null)
pstmt.close();
if(conn!=null)
conn.close();
}