Make rollback() and commit() no ops when no transaction is active

Gerrit code is using the construct:

  beginTransaction();
  try {
    insertPatchSetAncestors();
    insertPatchSets();
    updateChange();
    commit();
  } finally {
    rollback();
  }

Because beginTransaction() is optional in Gerrit code base commit()
set autoCommit=true on connection object, causing rollback() to fail
in finally block with:

  Cannot rollback when autoCommit is enabled.

To make rollback and commit operations successful in cases when no
transactions were started, make rollback() and commit() methods no ops
in this case.

Change-Id: I6633c490d4cbdaca5d0d400b1cd3fddb7bb45bad
diff --git a/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java b/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java
index 00310e4..758f727 100644
--- a/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java
+++ b/src/main/java/com/google/gwtorm/jdbc/JdbcSchema.java
@@ -51,7 +51,9 @@
   @Override
   public void commit() throws OrmException {
     try {
-      conn.commit();
+      if (!conn.getAutoCommit()) {
+        conn.commit();
+      }
     } catch (SQLException err) {
       throw new OrmException("Cannot commit transaction", err);
     } finally {
@@ -66,7 +68,9 @@
   @Override
   public void rollback() throws OrmException {
     try {
-      conn.rollback();
+      if (!conn.getAutoCommit()) {
+        conn.rollback();
+      }
     } catch (SQLException err) {
       throw new OrmException("Cannot rollback transaction", err);
     } finally {
diff --git a/src/test/java/com/google/gwtorm/schema/sql/DialectH2Test.java b/src/test/java/com/google/gwtorm/schema/sql/DialectH2Test.java
index db674fa..36f6533 100644
--- a/src/test/java/com/google/gwtorm/schema/sql/DialectH2Test.java
+++ b/src/test/java/com/google/gwtorm/schema/sql/DialectH2Test.java
@@ -209,6 +209,19 @@
   }
 
   @Test
+  public void testRollbackNoTransaction() throws SQLException, OrmException {
+    PhoneBookDb schema = phoneBook.open();
+    schema.updateSchema(executor);
+    ArrayList<Person> all = new ArrayList<Person>();
+    all.add(new Person(new Person.Key("Bob"), 18));
+    schema.people().insert(all);
+    schema.commit();
+    schema.rollback();
+    List<Person> r = schema.people().olderThan(10).toList();
+    assertEquals(1, r.size());
+  }
+
+  @Test
   public void testCommitTransaction() throws SQLException, OrmException {
     PhoneBookDb schema = phoneBook.open();
     schema.updateSchema(executor);
diff --git a/src/test/java/com/google/gwtorm/schema/sql/DialectMySQLTest.java b/src/test/java/com/google/gwtorm/schema/sql/DialectMySQLTest.java
index 4f0b255..c47a092 100644
--- a/src/test/java/com/google/gwtorm/schema/sql/DialectMySQLTest.java
+++ b/src/test/java/com/google/gwtorm/schema/sql/DialectMySQLTest.java
@@ -229,6 +229,19 @@
   }
 
   @Test
+  public void testRollbackNoTransaction() throws SQLException, OrmException {
+    PhoneBookDb schema = phoneBook.open();
+    schema.updateSchema(executor);
+    ArrayList<Person> all = new ArrayList<Person>();
+    all.add(new Person(new Person.Key("Bob"), 18));
+    schema.people().insert(all);
+    schema.commit();
+    schema.rollback();
+    List<Person> r = schema.people().olderThan(10).toList();
+    assertEquals(1, r.size());
+  }
+
+  @Test
   public void testCommitTransaction() throws SQLException, OrmException {
     PhoneBookDb schema = phoneBook.open();
     schema.updateSchema(executor);
diff --git a/src/test/java/com/google/gwtorm/schema/sql/DialectOracleSQLTest.java b/src/test/java/com/google/gwtorm/schema/sql/DialectOracleSQLTest.java
index b7d501c..3869dd5 100644
--- a/src/test/java/com/google/gwtorm/schema/sql/DialectOracleSQLTest.java
+++ b/src/test/java/com/google/gwtorm/schema/sql/DialectOracleSQLTest.java
@@ -229,6 +229,19 @@
   }
 
   @Test
+  public void testRollbackNoTransaction() throws SQLException, OrmException {
+    PhoneBookDb schema = phoneBook.open();
+    schema.updateSchema(executor);
+    ArrayList<Person> all = new ArrayList<Person>();
+    all.add(new Person(new Person.Key("Bob"), 18));
+    schema.people().insert(all);
+    schema.commit();
+    schema.rollback();
+    List<Person> r = schema.people().olderThan(10).toList();
+    assertEquals(1, r.size());
+  }
+
+  @Test
   public void testCommitTransaction() throws SQLException, OrmException {
     PhoneBookDb schema = phoneBook.open();
     schema.updateSchema(executor);
diff --git a/src/test/java/com/google/gwtorm/schema/sql/DialectPostgreSQLTest.java b/src/test/java/com/google/gwtorm/schema/sql/DialectPostgreSQLTest.java
index 6922aa5..e8612cc 100644
--- a/src/test/java/com/google/gwtorm/schema/sql/DialectPostgreSQLTest.java
+++ b/src/test/java/com/google/gwtorm/schema/sql/DialectPostgreSQLTest.java
@@ -54,9 +54,9 @@
   public void setUp() throws Exception {
     Class.forName(org.postgresql.Driver.class.getName());
 
-    final String database = "gwtorm";
-    final String user = "gwtorm";
-    final String pass = "gwtorm";
+    final String database = "reviewdb";
+    final String user = "gerrit2";
+    final String pass = "reviewdb";
 
     try {
       db = DriverManager.getConnection("jdbc:postgresql:" + database, user, pass);
@@ -228,6 +228,19 @@
   }
 
   @Test
+  public void testRollbackNoTransaction() throws SQLException, OrmException {
+    PhoneBookDb schema = phoneBook.open();
+    schema.updateSchema(executor);
+    ArrayList<Person> all = new ArrayList<Person>();
+    all.add(new Person(new Person.Key("Bob"), 18));
+    schema.people().insert(all);
+    schema.commit();
+    schema.rollback();
+    List<Person> r = schema.people().olderThan(10).toList();
+    assertEquals(1, r.size());
+  }
+
+  @Test
   public void testCommitTransaction() throws SQLException, OrmException {
     PhoneBookDb schema = phoneBook.open();
     schema.updateSchema(executor);