我有代码:
@Override
public void update(Duck entity) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = DriverManager.getConnection(daoProperties.getUrl(), daoProperties.getUser(), daoProperties.getPassword());
connection.setAutoCommit(false);
connection.commit()
preparedStatement = connection.prepareStatement(INSERT_FROG);
preparedStatement.setInt(ID, entity.getFrogId());
preparedStatement.setString(NAME, entity.getMyFrogFriend().name());
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
try {
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
try {
PreparedStatement duckPreparedStatement = connection.prepareStatement(INSERT_DUCK);
duckPreparedStatement.setInt(ID, entity.id());
//..
duckPreparedStatement.executeUpdate();
// throw new SQLException();
// connection.commit();
} catch (SQLException e) {
log.warning("error with statements or connection");
try {
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
我想,如果第二次插入失败,那么我们就不会进行第一次插入。但是此代码无效,如果我们删除第一个注释,则将完成第一个插入操作。我在做什么错?
try-catch
与rollback
应该在整个工作单元上。现在,您将在第一次失败后回滚,然后继续进行,好像什么都没发生。结果,第二个插入将在其自己的事务中(因此与第一个插入不同),并分别成功。
相反,您需要在两个语句(整个事务)之后回滚,而不是每个语句。
try {
// first insert
// second insert
} catch (SQLException e) {
connection.rollback();
}
顺便说一句,拥有commit()
之前您的工作单元没有任何意义,并且似乎表明事务管理总体中断。在工作单位之后注释掉commit()
的事实也不可取。如果关闭了连接,则将回滚事务(或使用某些数据库:已提交),如果重用连接,则将提交或回滚工作,具体取决于重新使用该连接的后续代码将执行的操作。