Merge "Removed transactions"
diff --git a/src/main/java/com/google/gwtorm/client/Access.java b/src/main/java/com/google/gwtorm/client/Access.java
index f535aa1..2f1fff9 100644
--- a/src/main/java/com/google/gwtorm/client/Access.java
+++ b/src/main/java/com/google/gwtorm/client/Access.java
@@ -106,17 +106,6 @@
   void insert(Iterable<T> instances) throws OrmException;
 
   /**
-   * Insert new entities into the data store.
-   *
-   * @param instances the instances to insert. The iteration occurs only once.
-   * @param txn transaction to batch the operation into. If not null the data
-   *        store changes will be delayed to {@link Transaction#commit()} is
-   *        invoked; if null the operation occurs immediately.
-   * @throws OrmException data insertion failed.
-   */
-  void insert(Iterable<T> instances, Transaction txn) throws OrmException;
-
-  /**
    * Immediately update existing entities in the data store.
    *
    * @param instances the instances to update. The iteration occurs only once.
@@ -126,18 +115,6 @@
   void update(Iterable<T> instances) throws OrmException;
 
   /**
-   * Update existing entities in the data store.
-   *
-   * @param instances the instances to update. The iteration occurs only once.
-   * @param txn transaction to batch the operation into. If not null the data
-   *        store changes will be delayed to {@link Transaction#commit()} is
-   *        invoked; if null the operation occurs immediately.
-   * @throws OrmException data modification failed.
-   * @throws UnsupportedOperationException no PrimaryKey was declared.
-   */
-  void update(Iterable<T> instances, Transaction txn) throws OrmException;
-
-  /**
    * Immediately update or insert entities in the data store.
    *
    * @param instances the instances to update. The iteration occurs only once.
@@ -147,18 +124,6 @@
   void upsert(Iterable<T> instances) throws OrmException;
 
   /**
-   * Update or insert entities in the data store.
-   *
-   * @param instances the instances to update. The iteration occurs only once.
-   * @param txn transaction to batch the operation into. If not null the data
-   *        store changes will be delayed to {@link Transaction#commit()} is
-   *        invoked; if null the operation occurs immediately.
-   * @throws OrmException data modification failed.
-   * @throws UnsupportedOperationException no PrimaryKey was declared.
-   */
-  void upsert(Iterable<T> instances, Transaction txn) throws OrmException;
-
-  /**
    * Immediately delete existing entities from the data store.
    *
    * @param keys the keys to delete. The iteration occurs only once.
@@ -177,18 +142,6 @@
   void delete(Iterable<T> instances) throws OrmException;
 
   /**
-   * Delete existing entities from the data store.
-   *
-   * @param instances the instances to delete. The iteration occurs only once.
-   * @param txn transaction to batch the operation into. If not null the data
-   *        store changes will be delayed to {@link Transaction#commit()} is
-   *        invoked; if null the operation occurs immediately.
-   * @throws OrmException data removal failed.
-   * @throws UnsupportedOperationException no PrimaryKey was declared.
-   */
-  void delete(Iterable<T> instances, Transaction txn) throws OrmException;
-
-  /**
    * Atomically update a single entity.
    * <p>
    * If the entity does not exist, the method returns {@code null} without
diff --git a/src/main/java/com/google/gwtorm/client/OrmRunnable.java b/src/main/java/com/google/gwtorm/client/OrmRunnable.java
deleted file mode 100644
index 4db3f51..0000000
--- a/src/main/java/com/google/gwtorm/client/OrmRunnable.java
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gwtorm.client;
-
-/**
- * Runs within an isolated database transaction, retrying if necessary.
- * <p>
- * The {@link Schema} is free to invoke this runnable multiple times if an
- * {@link OrmConcurrencyException} is thrown by the run method.
- *
- * @param <T> type of object the run method returns.
- * @param <S> type of schema the run method needs to perform its work.
- */
-public interface OrmRunnable<T, S extends Schema> {
-  /**
-   * Execute the task once.
-   * <p>
-   * Implementations should read any state they need within the method, to
-   * ensure they are looking at the most current copy of the data from the
-   * database. If a method is invoked a second time to recover from a
-   * concurrency error it would need to read the data again.
-   *
-   * @param db active schema handle to query through, and make updates on.
-   * @param txn the current transaction handle. Commit is invoked by the caller.
-   * @param retry true if this is not the first attempt to execute this task.
-   * @return the return value of the function, if any.
-   * @throws OrmException any database error. {@link OrmConcurrencyException}
-   *         may cause the transaction to be retried.
-   */
-  T run(S db, Transaction txn, boolean retry) throws OrmException;
-}
diff --git a/src/main/java/com/google/gwtorm/client/Schema.java b/src/main/java/com/google/gwtorm/client/Schema.java
index 2739177..28bfd25 100644
--- a/src/main/java/com/google/gwtorm/client/Schema.java
+++ b/src/main/java/com/google/gwtorm/client/Schema.java
@@ -78,30 +78,6 @@
   void pruneSchema(StatementExecutor e) throws OrmException;
 
   /**
-   * Begin a new transaction.
-   * <p>
-   * Only one transaction can be in-flight at a time on any given Schema
-   * instance. Applications must commit or rollback a previously created
-   * transaction before beginning another transaction on the same Schema.
-   *
-   * @return the new transaction.
-   * @throws OrmException the schema has been closed or another transaction has
-   *         already been begun on this schema instance.
-   */
-  Transaction beginTransaction() throws OrmException;
-
-  /**
-   * Execute a task within a transaction, restarting it if necessary.
-   *
-   * @param <T> type of return value for the task.
-   * @param <S> type of <code>this</code>.
-   * @param task the task to execute.
-   * @return the return value of the task.
-   * @throws OrmException the task could not be completed successfully.
-   */
-  <T, S extends Schema> T run(OrmRunnable<T, S> task) throws OrmException;
-
-  /**
    * Close the schema and release all resources.
    */
   void close();
diff --git a/src/main/java/com/google/gwtorm/client/Transaction.java b/src/main/java/com/google/gwtorm/client/Transaction.java
deleted file mode 100644
index 0780ab4..0000000
--- a/src/main/java/com/google/gwtorm/client/Transaction.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gwtorm.client;
-
-/**
- * An active transaction running on a {@link Schema}.
- * <p>
- * Applications must invoke {@link #commit()} to finish a transaction.
- * <p>
- * Use method on one or more {@link Access} instances to schedule changes into
- * an open transaction:
- * <ul>
- * <li>{@link Access#insert(Iterable, Transaction)}</li>
- * <li>{@link Access#update(Iterable, Transaction)}</li>
- * <li>{@link Access#delete(Iterable, Transaction)}</li>
- * <ul>
- *
- * @see Schema#beginTransaction()
- */
-public interface Transaction {
-  /**
-   * Commit this transaction, finishing all actions.
-   *
-   * @throws OrmException data store refused/rejected one or more actions.
-   */
-  void commit() throws OrmException;
-
-  /**
-   * Rollback (abort) this transaction, performing none of the actions.
-   * <p>
-   * This method has no affect if the transaction has not made any changes.
-   *
-   * @throws OrmException data store couldn't undo the transaction, as it is
-   *         already committed.
-   */
-  void rollback() throws OrmException;
-}
diff --git a/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java b/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java
index bd66e34..e192d30 100644
--- a/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java
+++ b/src/main/java/com/google/gwtorm/client/impl/AbstractAccess.java
@@ -15,17 +15,15 @@
 package com.google.gwtorm.client.impl;
 
 import com.google.gwtorm.client.Access;
-import com.google.gwtorm.client.AtomicUpdate;
 import com.google.gwtorm.client.Key;
 import com.google.gwtorm.client.OrmException;
 import com.google.gwtorm.client.ResultSet;
-import com.google.gwtorm.client.Transaction;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
-public abstract class AbstractAccess<E, K extends Key<?>, T extends AbstractTransaction>
+public abstract class AbstractAccess<E, K extends Key<?>>
     implements Access<E, K> {
   public ResultSet<E> get(final Iterable<K> keys) throws OrmException {
     final ArrayList<E> r = new ArrayList<E>();
@@ -53,71 +51,31 @@
   }
 
   public final void insert(final Iterable<E> instances) throws OrmException {
-    doInsert(instances, null);
-  }
-
-  public final void insert(final Iterable<E> instances, final Transaction txn)
-      throws OrmException {
-    if (txn != null) {
-      cast(txn).queueInsert(this, instances);
-    } else {
-      insert(instances);
-    }
+    doInsert(instances);
   }
 
   public final void update(final Iterable<E> instances) throws OrmException {
-    doUpdate(instances, null);
-  }
-
-  public final void update(final Iterable<E> instances, final Transaction txn)
-      throws OrmException {
-    if (txn != null) {
-      cast(txn).queueUpdate(this, instances);
-    } else {
-      update(instances);
-    }
+    doUpdate(instances);
   }
 
   public final void upsert(final Iterable<E> instances) throws OrmException {
-    doUpsert(instances, null);
-  }
-
-  public final void upsert(final Iterable<E> instances, final Transaction txn)
-      throws OrmException {
-    if (txn != null) {
-      cast(txn).queueUpsert(this, instances);
-    } else {
-      upsert(instances);
-    }
+    doUpsert(instances);
   }
 
   public final void delete(final Iterable<E> instances) throws OrmException {
-    doDelete(instances, null);
+    doDelete(instances);
   }
 
-  public final void delete(final Iterable<E> instances, final Transaction txn)
-      throws OrmException {
-    if (txn != null) {
-      cast(txn).queueDelete(this, instances);
-    } else {
-      delete(instances);
-    }
-  }
-
-  protected abstract void doInsert(Iterable<E> instances, T txn)
+  protected abstract void doInsert(Iterable<E> instances)
       throws OrmException;
 
-  protected abstract void doUpdate(Iterable<E> instances, T txn)
+  protected abstract void doUpdate(Iterable<E> instances)
       throws OrmException;
 
-  protected abstract void doUpsert(Iterable<E> instances, T txn)
+  protected abstract void doUpsert(Iterable<E> instances)
       throws OrmException;
 
-  protected abstract void doDelete(Iterable<E> instances, T txn)
+  protected abstract void doDelete(Iterable<E> instances)
       throws OrmException;
 
-  @SuppressWarnings("unchecked")
-  private T cast(final Transaction txn) {
-    return ((T) txn);
-  }
 }
diff --git a/src/main/java/com/google/gwtorm/client/impl/AbstractTransaction.java b/src/main/java/com/google/gwtorm/client/impl/AbstractTransaction.java
deleted file mode 100644
index def8385..0000000
--- a/src/main/java/com/google/gwtorm/client/impl/AbstractTransaction.java
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gwtorm.client.impl;
-
-import com.google.gwtorm.client.Key;
-import com.google.gwtorm.client.OrmException;
-import com.google.gwtorm.client.Transaction;
-
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-public abstract class AbstractTransaction implements Transaction {
-  private static LinkedHashMap<Object, Action<?, Key<?>, AbstractTransaction>> newMap() {
-    return new LinkedHashMap<Object, Action<?, Key<?>, AbstractTransaction>>();
-  }
-
-  protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingInsert;
-  protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingUpdate;
-  protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingUpsert;
-  protected final Map<Object, Action<?, Key<?>, AbstractTransaction>> pendingDelete;
-
-  protected AbstractTransaction() {
-    pendingInsert = newMap();
-    pendingUpdate = newMap();
-    pendingUpsert = newMap();
-    pendingDelete = newMap();
-  }
-
-  public void commit() throws OrmException {
-    for (Action<?, Key<?>, AbstractTransaction> a : pendingDelete.values()) {
-      a.doDelete(this);
-    }
-    for (Action<?, Key<?>, AbstractTransaction> a : pendingInsert.values()) {
-      a.doInsert(this);
-    }
-    for (Action<?, Key<?>, AbstractTransaction> a : pendingUpdate.values()) {
-      a.doUpdate(this);
-    }
-    for (Action<?, Key<?>, AbstractTransaction> a : pendingUpsert.values()) {
-      a.doUpsert(this);
-    }
-  }
-
-  <E, K extends Key<?>, T extends AbstractTransaction> void queueInsert(
-      final AbstractAccess<E, ?, T> access, final Iterable<E> list) {
-    queue(pendingInsert, access, list);
-  }
-
-  <E, K extends Key<?>, T extends AbstractTransaction> void queueUpdate(
-      final AbstractAccess<E, ?, T> access, final Iterable<E> list) {
-    queue(pendingUpdate, access, list);
-  }
-
-  <E, K extends Key<?>, T extends AbstractTransaction> void queueUpsert(
-      final AbstractAccess<E, ?, T> access, final Iterable<E> list) {
-    queue(pendingUpsert, access, list);
-  }
-
-  <E, K extends Key<?>, T extends AbstractTransaction> void queueDelete(
-      final AbstractAccess<E, ?, T> access, final Iterable<E> list) {
-    queue(pendingDelete, access, list);
-  }
-
-  private static <E, K extends Key<?>, T extends AbstractTransaction> void queue(
-      final Map<Object, Action<?, Key<?>, AbstractTransaction>> queue,
-      final AbstractAccess<E, K, T> access, final Iterable<E> list) {
-    Action<E, K, T> c = get(queue, access);
-    if (c == null) {
-      c = new Action<E, K, T>(access);
-      put(queue, c);
-    }
-    c.addAll(list);
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <E, K extends Key<?>, T extends AbstractTransaction> Action<E, K, T> get(
-      final Map<Object, Action<?, Key<?>, AbstractTransaction>> q,
-      final AbstractAccess<E, K, T> access) {
-    return (Action<E, K, T>) q.get(access);
-  }
-
-  @SuppressWarnings("unchecked")
-  private static <E, K extends Key<?>, T extends AbstractTransaction> void put(
-      final Map queue, Action<E, K, T> c) {
-    // This silly little method was needed to defeat the Java compiler's
-    // generic type checking. Somehow we got lost in the anonymous types
-    // from all the ? in our Map definition and the compiler just won't let
-    // us do a put into the map.
-    //
-    queue.put(c.access, c);
-  }
-
-  private static class Action<E, K extends Key<?>, T extends AbstractTransaction> {
-    private final AbstractAccess<E, K, T> access;
-    private final Set<E> instances;
-
-    Action(final AbstractAccess<E, K, T> a) {
-      access = a;
-      instances = new LinkedHashSet<E>();
-    }
-
-    void addAll(final Iterable<E> list) {
-      for (final E o : list) {
-        instances.add(o);
-      }
-    }
-
-    void doInsert(final T t) throws OrmException {
-      access.doInsert(instances, t);
-    }
-
-    void doUpdate(final T t) throws OrmException {
-      access.doUpdate(instances, t);
-    }
-
-    void doUpsert(final T t) throws OrmException {
-      access.doUpsert(instances, t);
-    }
-
-    void doDelete(final T t) throws OrmException {
-      access.doDelete(instances, t);
-    }
-  }
-}
diff --git a/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java b/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
index e54df99..351e825 100644
--- a/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
+++ b/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
@@ -19,8 +19,6 @@
 import com.google.gwtorm.client.Key;
 import com.google.gwtorm.client.OrmConcurrencyException;
 import com.google.gwtorm.client.OrmException;
-import com.google.gwtorm.client.OrmRunnable;
-import com.google.gwtorm.client.Transaction;
 import com.google.gwtorm.client.impl.AbstractAccess;
 import com.google.gwtorm.client.impl.ListResultSet;
 
@@ -33,7 +31,9 @@
 
 /** Internal base class for implementations of {@link Access}. */
 public abstract class JdbcAccess<T, K extends Key<?>> extends
-    AbstractAccess<T, K, JdbcTransaction> {
+    AbstractAccess<T, K> {
+  private static final int MAX_TRIES = 10;
+
   private final JdbcSchema schema;
 
   protected JdbcAccess(final JdbcSchema s) {
@@ -154,8 +154,7 @@
   }
 
   @Override
-  protected void doInsert(final Iterable<T> instances, final JdbcTransaction txn)
-      throws OrmException {
+  protected void doInsert(final Iterable<T> instances) throws OrmException {
     try {
       PreparedStatement ps = null;
       try {
@@ -180,8 +179,7 @@
   }
 
   @Override
-  protected void doUpdate(final Iterable<T> instances, final JdbcTransaction txn)
-      throws OrmException {
+  protected void doUpdate(final Iterable<T> instances) throws OrmException {
     try {
       PreparedStatement ps = null;
       try {
@@ -206,8 +204,7 @@
   }
 
   @Override
-  protected void doUpsert(final Iterable<T> instances, final JdbcTransaction txn)
-      throws OrmException {
+  protected void doUpsert(final Iterable<T> instances) throws OrmException {
     // Assume update first, it will cheaply tell us if the row is missing.
     //
     Collection<T> inserts = null;
@@ -254,13 +251,12 @@
     }
 
     if (inserts != null) {
-      doInsert(inserts, txn);
+      doInsert(inserts);
     }
   }
 
   @Override
-  protected void doDelete(final Iterable<T> instances, final JdbcTransaction txn)
-      throws OrmException {
+  protected void doDelete(final Iterable<T> instances) throws OrmException {
     try {
       PreparedStatement ps = null;
       try {
@@ -304,19 +300,24 @@
   @Override
   public T atomicUpdate(final K key, final AtomicUpdate<T> update)
       throws OrmException {
-    return schema.run(new OrmRunnable<T, JdbcSchema>() {
-      @Override
-      public T run(JdbcSchema db, Transaction txn, boolean retry)
-          throws OrmException {
+
+    for (int attempts = 1;; attempts++) {
+      try {
         final T obj = get(key);
         if (obj == null) {
           return null;
         }
         final T res = update.update(obj);
-        update(Collections.singleton(obj), txn);
+        update(Collections.singleton(obj));
         return res;
+      } catch (OrmConcurrencyException err) {
+        if (attempts < MAX_TRIES) {
+          continue;
+        }
+        throw err;
       }
-    });
+    }
+
   }
 
   @Override
diff --git a/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java b/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java
index a587cf1..997ed08 100644
--- a/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java
+++ b/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java
@@ -14,12 +14,9 @@
 
 package com.google.gwtorm.jdbc;
 
-import com.google.gwtorm.client.OrmConcurrencyException;
 import com.google.gwtorm.client.OrmException;
-import com.google.gwtorm.client.OrmRunnable;
 import com.google.gwtorm.client.Schema;
 import com.google.gwtorm.client.StatementExecutor;
-import com.google.gwtorm.client.Transaction;
 import com.google.gwtorm.schema.ColumnModel;
 import com.google.gwtorm.schema.RelationModel;
 import com.google.gwtorm.schema.SchemaModel;
@@ -34,7 +31,6 @@
 
 /** Internal base class for implementations of {@link Schema}. */
 public abstract class JdbcSchema implements Schema {
-  private static final int MAX_TRIES = 10;
   private final Database<?> dbDef;
   private Connection conn;
 
@@ -51,27 +47,6 @@
     return dbDef.getDialect();
   }
 
-  public <T, S extends Schema> T run(final OrmRunnable<T, S> task)
-      throws OrmException {
-    for (int attempts = 1;; attempts++) {
-      try {
-        final Transaction txn = beginTransaction();
-        try {
-          return task.run((S) this, txn, attempts > 1);
-        } finally {
-          txn.commit();
-        }
-      } catch (OrmConcurrencyException err) {
-        // If the commit failed, our implementation rolled back automatically.
-        //
-        if (attempts < MAX_TRIES) {
-          continue;
-        }
-        throw err;
-      }
-    }
-  }
-
   public void updateSchema(final StatementExecutor e) throws OrmException {
     try {
       createSequences(e);
@@ -218,10 +193,6 @@
     return getDialect().nextLong(getConnection(), query);
   }
 
-  public Transaction beginTransaction() {
-    return new JdbcTransaction(this);
-  }
-
   public void close() {
     if (conn != null) {
       try {
diff --git a/src/main/java/com/google/gwtorm/jdbc/JdbcTransaction.java b/src/main/java/com/google/gwtorm/jdbc/JdbcTransaction.java
deleted file mode 100644
index 80cf804..0000000
--- a/src/main/java/com/google/gwtorm/jdbc/JdbcTransaction.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gwtorm.jdbc;
-
-import com.google.gwtorm.client.OrmException;
-import com.google.gwtorm.client.Transaction;
-import com.google.gwtorm.client.impl.AbstractTransaction;
-
-import java.sql.SQLException;
-
-/** Implementation of the {@link Transaction} interface, on JDBC. */
-class JdbcTransaction extends AbstractTransaction {
-  private final JdbcSchema schema;
-  private boolean inProgress;
-  private boolean committed;
-
-  JdbcTransaction(final JdbcSchema s) {
-    schema = s;
-  }
-
-  @Override
-  public void commit() throws OrmException {
-    notCommitted();
-
-    if (!inProgress) {
-      try {
-        schema.getConnection().setAutoCommit(false);
-      } catch (SQLException e) {
-        throw new OrmException("Cannot start transaction", e);
-      }
-      inProgress = true;
-    }
-
-    try {
-      super.commit();
-    } catch (OrmException e) {
-      try {
-        rollback();
-      } catch (OrmException e2) {
-        // Ignore the cascaded rollback error.
-      }
-      throw e;
-    } catch (RuntimeException e) {
-      try {
-        rollback();
-      } catch (OrmException e2) {
-        // Ignore the cascaded rollback error.
-      }
-      throw e;
-    }
-
-    try {
-      schema.getConnection().commit();
-      committed = true;
-    } catch (SQLException e) {
-      throw new OrmException("Transaction failed", e);
-    } finally {
-      exitTransaction();
-    }
-  }
-
-  public void rollback() throws OrmException {
-    notCommitted();
-
-    if (inProgress) {
-      try {
-        schema.getConnection().rollback();
-      } catch (SQLException e) {
-        throw new OrmException("Rollback failed", e);
-      } finally {
-        exitTransaction();
-      }
-    }
-  }
-
-  private void notCommitted() throws OrmException {
-    if (committed) {
-      throw new OrmException("Transaction already committed");
-    }
-  }
-
-  private void exitTransaction() {
-    try {
-      schema.getConnection().setAutoCommit(true);
-    } catch (SQLException e) {
-    } finally {
-      inProgress = false;
-    }
-  }
-}
diff --git a/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java b/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
index 2ffdebd..2099303 100644
--- a/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
+++ b/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
@@ -16,7 +16,6 @@
 
 import com.google.gwtorm.client.OrmConcurrencyException;
 import com.google.gwtorm.client.OrmException;
-import com.google.gwtorm.client.Transaction;
 import com.google.gwtorm.data.PersonAccess;
 import com.google.gwtorm.data.PhoneBookDb;
 import com.google.gwtorm.data.TestPerson;
@@ -197,34 +196,6 @@
     st.close();
   }
 
-  public void testInsertManyPeopleByTransaction() throws Exception {
-    final PhoneBookDb schema = openAndCreate();
-    final Transaction txn = schema.beginTransaction();
-    final ArrayList<TestPerson> all = new ArrayList<TestPerson>();
-    all.add(new TestPerson(new TestPerson.Key("Bob"), 18));
-    all.add(new TestPerson(new TestPerson.Key("Mary"), 22));
-    all.add(new TestPerson(new TestPerson.Key("Zak"), 33));
-    schema.people().insert(all, txn);
-
-    final Statement st = statement(schema);
-    ResultSet rs;
-
-    rs = st.executeQuery("SELECT name,age FROM people ORDER BY name");
-    assertFalse(rs.next());
-    rs.close();
-
-    txn.commit();
-    rs = st.executeQuery("SELECT name,age FROM people ORDER BY name");
-    for (int rowIdx = 0; rowIdx < all.size(); rowIdx++) {
-      assertTrue(rs.next());
-      assertEquals(all.get(rowIdx).name(), rs.getString(1));
-      assertEquals(all.get(rowIdx).age(), rs.getInt(2));
-    }
-    assertFalse(rs.next());
-    rs.close();
-    st.close();
-  }
-
   public void testDeleteOnePerson() throws Exception {
     final PhoneBookDb schema = openAndCreate();
     final TestPerson bob = new TestPerson(new TestPerson.Key("Bob"), 18);