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]
# 1
If this is a copy of your code - the writer seems to have to thick fingers ;-)The second sql-statement (GET_LAST_INSERTED_MENU_ID) starts with XSELECT but SELECT would succeed.
Sucharda at 2007-7-12 20:39:08 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...
# 2
Suchard, thanks for the response, but as describe in the original posting, I created the typo on purpose to force the SQLException and the (supposed) rollback.
mgrommeta at 2007-7-12 20:39:08 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...
# 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();

}

George123a at 2007-7-12 20:39:08 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...
# 4
George123,Thanks for responding. Using getGeneratedKeys() is not supported by Oracle's JDBC libraries...Thats why I'm trying to use a sequence.The conn.setAutoCommit(true) is interesting -- I've not seen that anywhere else... Can you explain the logic behind this?
mgrommeta at 2007-7-12 20:39:08 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...