function testRollback() {
  var scope = [j, e];
  var newJobId = 'SomeUniqueId';

  return tx.begin(scope).then(function() {
    // Adding a new job row.
    var newJob = j.createRow();
    newJob.setId(newJobId);
    var q1 = db.insert().into(j).values([newJob]);
    return tx.attach(q1);
  }).then(function(results) {
    var q2 = db.select().from(j).where(j.id.eq(newJobId));
    return tx.attach(q2);
  }).then(function(results) {
    assertEquals(1, results.length);

    var q3 = db.select().from(j);
    return tx.attach(q3);
  }).then(function(results) {
    assertEquals(sampleJobs.length + 1, results.length);

    return tx.rollback();
  }).then(function() {
    // Checking that the transaction has been finalized.
    // 107: Invalid transaction state transition: {0} -> {1}.
    lf.testing.util.assertThrowsError(107, attachFn);
    lf.testing.util.assertThrowsError(107, commitFn);
    lf.testing.util.assertThrowsError(107, rollbackFn);
    lf.testing.util.assertThrowsError(107, beginFn);

    return lf.testing.util.selectAll(global, j);
  }).then(function(results) {
    // Checking that the entire transaction was rolled back, and therefore that
    // Job row that had been added does not appear on disk.
    assertEquals(sampleJobs.length, results.length);

    // Expecting all locks to have been released by previous transaction, which
    // should allow the following query to complete.
    return db.select().from(j).exec();
  }).then(function() {
    var stats = tx.stats();
    assertFalse(stats.success());
    assertEquals(0, stats.insertedRowCount());
    assertEquals(0, stats.updatedRowCount());
    assertEquals(0, stats.deletedRowCount());
    assertEquals(0, stats.changedTableCount());
  });
}
Tests that when a transaction is explicitly rolled back, all changes that
were made as part of this transaction are discarded.
@return {!IThenable}