code: public synchronized void withTransaction(Closure closure) throws SQLException {
          boolean savedCacheConnection = cacheConnection;
          cacheConnection = true;
          Connection connection = null;
          boolean savedAutoCommit = true;
          try {
              connection = createConnection();
              savedAutoCommit = connection.getAutoCommit();
              connection.setAutoCommit(false);
              callClosurePossiblyWithConnection(closure, connection);
              connection.commit();
          } catch (SQLException e) {
              handleError(connection, e);
              throw e;
          } catch (RuntimeException e) {
              handleError(connection, e);
              throw e;
          } catch (Error e) {
              handleError(connection, e);
              throw e;
          } catch (Exception e) {
              handleError(connection, e);
              throw new SQLException("Unexpected exception during transaction", e);
          } finally {
              if (connection != null) {
                  try {
                      connection.setAutoCommit(savedAutoCommit);
                  }
                  catch (SQLException e) {
                      LOG.finest("Caught exception resetting auto commit: " + e.getMessage() + " - continuing");
                  }
              }
              cacheConnection = false;
              closeResources(connection, null);
              cacheConnection = savedCacheConnection;
              if (dataSource != null && !cacheConnection) {
                  useConnection = null;
              }
          }
      }
docs: Performs the closure within a transaction using a cached connection.
  If the closure takes a single argument, it will be called
  with the connection, otherwise it will be called with no arguments.
  
  @param closure the given closure
  @throws SQLException if a database error occurs