/** Fully roll back the current transaction. */ public void rollback() { checkCommitRollback(); currentTransactionName = null; boolean needCommit = false; if (locks.size() > 0 || needCommit) { database.commit(this); } cleanTempTables(false); if (autoCommitAtTransactionEnd) { autoCommit = true; autoCommitAtTransactionEnd = false; } endTransaction(); List<SQLException> rollbackExceptions = New.arrayList(); for (Map.Entry<String, Connection> entry : connectionHolder.entrySet()) { try { entry.getValue().rollback(); } catch (SQLException ex) { rollbackExceptions.add(ex); } } if (!rollbackExceptions.isEmpty()) { throw DbException.convert(rollbackExceptions.get(0)); } }
/** * Undo all operations back to the log position of the given savepoint. * * @param name the savepoint name */ public void rollbackToSavepoint(String name) { checkCommitRollback(); if (savepoints == null) { throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name); } Savepoint savepoint = savepoints.get(name); if (savepoint == null) { throw DbException.get(ErrorCode.SAVEPOINT_IS_INVALID_1, name); } rollbackTo(savepoint, false); }
/** * Commit the current transaction. If the statement was not a data definition statement, and if * there are temporary tables that should be dropped or truncated at commit, this is done as well. * * @param ddl if the statement was a data definition statement */ public void commit(boolean ddl) { checkCommitRollback(); currentTransactionName = null; transactionStart = 0; if (containsUncommitted()) { // need to commit even if rollback is not possible // (create/drop table and so on) database.commit(this); } if (temporaryLobs != null) { for (Value v : temporaryLobs) { if (!v.isLinked()) { v.close(); } } temporaryLobs.clear(); } if (!ddl) { // do not clean the temp tables if the last command was a // create/drop cleanTempTables(false); if (autoCommitAtTransactionEnd) { autoCommit = true; autoCommitAtTransactionEnd = false; } } endTransaction(); boolean commit = true; List<SQLException> commitExceptions = New.arrayList(); StringBuilder buf = new StringBuilder(); for (Map.Entry<String, Connection> entry : connectionHolder.entrySet()) { if (commit) { try { entry.getValue().commit(); buf.append("\ncommit shard " + entry.getKey() + " transaction succeed."); } catch (SQLException ex) { commit = false; commitExceptions.add(ex); buf.append("\ncommit shard " + entry.getKey() + " transaction failure."); } } else { // after unsucessfull commit we must try to rollback // remaining connections try { entry.getValue().rollback(); buf.append("\nrollback shard " + entry.getKey() + " transaction succeed."); } catch (SQLException ex) { buf.append("\nrollback shard " + entry.getKey() + " transaction failure."); } } } if (commitExceptions.isEmpty()) { trace.debug("commit multiple group transaction succeed. commit track list:{0}", buf); } else { trace.error( commitExceptions.get(0), "fail to commit multiple group transaction. commit track list:{0}", buf); DbException.convert(commitExceptions.get(0)); } }