private int updateRecords() throws Throwable {
   ODatabaseDocumentTx database = null;
   try {
     database = ODatabaseDocumentPool.global().acquire(getDatabaseURL(), "admin", "admin");
     int numRetries = 0;
     int numUpdated = 0;
     while (numRetries < NUM_RETRIES) {
       database.begin();
       try {
         OCommandSQL cmd =
             new OCommandSQL("UPDATE ExceptionRecord set jobId='2' where username='******'");
         numUpdated = database.command(cmd).execute((Object[]) null);
         database.commit();
         break;
       } catch (Throwable e) {
         database.rollback();
         logger.log(Level.SEVERE, "********************************");
         logger.log(Level.SEVERE, "Update Iteration=" + numRetries + ", " + e.toString(), e);
         logger.log(Level.SEVERE, "********************************");
         if (numRetries++ == NUM_RETRIES) {
           throw e;
         }
       }
     }
     return numUpdated;
   } finally {
     if (database != null && !database.isClosed()) {
       database.close();
     }
   }
 }
  @Test
  public void test3RollbackWithCopyCacheStrategy() throws IOException {
    database1 = new ODatabaseDocumentTx(url).open("admin", "admin");
    database2 = new ODatabaseDocumentTx(url).open("admin", "admin");

    database1.getLevel2Cache().setStrategy(STRATEGY.COPY_RECORD);

    // Create docA.
    ODocument vDocA_db1 = database1.newInstance();
    vDocA_db1.field(NAME, "docA");
    database1.save(vDocA_db1);

    // Keep the IDs.
    ORID vDocA_Rid = vDocA_db1.getIdentity().copy();

    database2.begin(TXTYPE.OPTIMISTIC);
    try {
      // Get docA and update in db2 transaction context
      ODocument vDocA_db2 = database2.load(vDocA_Rid);
      vDocA_db2.field(NAME, "docA_v2");
      database2.save(vDocA_db2);

      database1.begin(TXTYPE.OPTIMISTIC);
      try {
        vDocA_db1.field(NAME, "docA_v3");
        database1.save(vDocA_db1);
        database1.commit();
      } catch (OConcurrentModificationException e) {
        Assert.fail("Should not failed here...");
      }
      Assert.assertEquals(vDocA_db1.field(NAME), "docA_v3");

      // Will throw OConcurrentModificationException
      database2.commit();
      Assert.fail("Should throw OConcurrentModificationException");
    } catch (OConcurrentModificationException e) {
      database2.rollback();
    }

    // Force reload all (to be sure it is not a cache problem)
    database1.close();
    database2.close();
    database2 = new ODatabaseDocumentTx(url).open("admin", "admin");

    // docB should be in the last state : "docA_v3"
    ODocument vDocB_db2 = database2.load(vDocA_Rid);
    Assert.assertEquals(vDocB_db2.field(NAME), "docA_v3");

    database1.close();
    database2.close();
  }
  private void createExceptionRecords(int count, boolean batch) throws Exception {
    ODatabaseDocumentTx database = null;
    try {
      database = ODatabaseDocumentPool.global().acquire(getDatabaseURL(), "admin", "admin");
      database.begin();
      for (int x = 0; x < count; x++) {
        String ID = UUID.randomUUID().toString();
        ODocument document = database.newInstance("ExceptionRecord");
        document.field("id", ID);
        document.field("data", DATA);
        document.field("status", "original");
        document.field("approved", false);
        document.field("groupNonException", false);
        document.field("comment", "");
        document.field("jobId", "1");
        document.field("dataflowName", "Error_Handling_V5");
        document.field("username", "admin");
        document.field("timestamp", new Date().getTime());
        document.field("stageLabel", "Exception Monitor");
        document.field("groupColumn", "");
        document.field("lastModifiedBy", "admin");
        document.field("lastModified", new Date());
        database.save(document);

        createExceptionRecordVersion(database, ID, "1");
        if (batch && (x % BATCH_SIZE) == 0) {
          System.out.println("Committing batch of " + BATCH_SIZE);
          database.commit();
          database.begin();
        }
      }
      database.commit();
    } catch (Throwable e) {
      database.rollback();
      throw e;
    } finally {
      if (database != null) {
        database.close();
      }
    }
  }
 private int deleteRecordsWithLimit() throws Throwable {
   ODatabaseDocumentTx database = null;
   try {
     database = ODatabaseDocumentPool.global().acquire(getDatabaseURL(), "admin", "admin");
     int numRetries = 0;
     int numDeleted = 0;
     while (numRetries < NUM_RETRIES) {
       try {
         int deletedBatch = 0;
         do {
           database.begin();
           OCommandSQL cmd =
               new OCommandSQL(
                   "DELETE from ExceptionRecord where username='******' LIMIT " + BATCH_SIZE);
           deletedBatch = database.command(cmd).execute((Object[]) null);
           numDeleted += deletedBatch;
           database.commit();
         } while (deletedBatch > 0);
         break;
       } catch (Throwable e) {
         database.rollback();
         logger.log(Level.SEVERE, "********************************");
         logger.log(Level.SEVERE, "Delete Iteration=" + numRetries + ", " + e.toString(), e);
         logger.log(Level.SEVERE, "********************************");
         if (numRetries++ == NUM_RETRIES) {
           throw e;
         }
       }
     }
     return numDeleted;
   } finally {
     if (database != null && !database.isClosed()) {
       database.close();
     }
   }
 }
  public void TransactionRollbackConstistencyTest() {
    System.out.println(
        "**************************TransactionRollbackConsistencyTest***************************************");
    ODatabaseDocumentTx db = new ODatabaseDocumentTx(url);
    db.open("admin", "admin");
    OClass vertexClass = db.getMetadata().getSchema().createClass("TRVertex");
    OClass edgeClass = db.getMetadata().getSchema().createClass("TREdge");
    vertexClass.createProperty("in", OType.LINKSET, edgeClass);
    vertexClass.createProperty("out", OType.LINKSET, edgeClass);
    edgeClass.createProperty("in", OType.LINK, vertexClass);
    edgeClass.createProperty("out", OType.LINK, vertexClass);

    OClass personClass = db.getMetadata().getSchema().createClass("TRPerson", vertexClass);
    personClass.createProperty("name", OType.STRING).createIndex(OClass.INDEX_TYPE.UNIQUE);
    personClass.createProperty("surname", OType.STRING).createIndex(OClass.INDEX_TYPE.NOTUNIQUE);
    personClass.createProperty("version", OType.INTEGER);

    db.getMetadata().getSchema().save();
    db.close();

    final int cnt = 4;

    db.open("admin", "admin");
    db.begin();
    Vector inserted = new Vector();

    for (int i = 0; i < cnt; i++) {
      ODocument person = new ODocument("TRPerson");
      person.field("name", Character.toString((char) ('A' + i)));
      person.field("surname", Character.toString((char) ('A' + (i % 3))));
      person.field("myversion", 0);
      person.field("in", new HashSet<ODocument>());
      person.field("out", new HashSet<ODocument>());

      if (i >= 1) {
        ODocument edge = new ODocument("TREdge");
        edge.field("in", person.getIdentity());
        edge.field("out", inserted.elementAt(i - 1));
        ((HashSet<ODocument>) person.field("out")).add(edge);
        ((HashSet<ODocument>) ((ODocument) inserted.elementAt(i - 1)).field("in")).add(edge);
        edge.save();
      }
      inserted.add(person);
      person.save();
    }
    db.commit();

    final List<ODocument> result1 = db.command(new OCommandSQL("select from TRPerson")).execute();
    Assert.assertNotNull(result1);
    Assert.assertEquals(result1.size(), cnt);
    System.out.println("Before transaction commit");
    for (ODocument d : result1) System.out.println(d);

    try {
      db.begin();
      Vector inserted2 = new Vector();

      for (int i = 0; i < cnt; i++) {
        ODocument person = new ODocument("TRPerson");
        person.field("name", Character.toString((char) ('a' + i)));
        person.field("surname", Character.toString((char) ('a' + (i % 3))));
        person.field("myversion", 0);
        person.field("in", new HashSet<ODocument>());
        person.field("out", new HashSet<ODocument>());

        if (i >= 1) {
          ODocument edge = new ODocument("TREdge");
          edge.field("in", person.getIdentity());
          edge.field("out", inserted2.elementAt(i - 1));
          ((HashSet<ODocument>) person.field("out")).add(edge);
          ((HashSet<ODocument>) ((ODocument) inserted2.elementAt(i - 1)).field("in")).add(edge);
          edge.save();
        }
        inserted2.add(person);
        person.save();
      }

      for (int i = 0; i < cnt; i++) {
        if (i != cnt - 1) {
          ((ODocument) inserted.elementAt(i)).field("myversion", 2);
          ((ODocument) inserted.elementAt(i)).save();
        }
      }

      ((ODocument) inserted.elementAt(cnt - 1)).delete();
      ((ODocument) inserted.elementAt(cnt - 2)).getRecordVersion().reset();
      ((ODocument) inserted.elementAt(cnt - 2)).save();
      db.commit();
      Assert.assertTrue(false);
    } catch (OConcurrentModificationException e) {
      Assert.assertTrue(true);
      db.rollback();
    }

    final List<ODocument> result2 = db.command(new OCommandSQL("select from TRPerson")).execute();
    Assert.assertNotNull(result2);
    System.out.println("After transaction commit failure/rollback");
    for (ODocument d : result2) System.out.println(d);
    Assert.assertEquals(result2.size(), cnt);

    db.close();
    System.out.println(
        "**************************TransactionRollbackConstistencyTest***************************************");
  }
  @Test
  public void test1RollbackOnConcurrentException() throws IOException {
    database1 = new ODatabaseDocumentTx(url).open("admin", "admin");
    database2 = new ODatabaseDocumentTx(url).open("admin", "admin");

    database1.begin(TXTYPE.OPTIMISTIC);

    // Create docA.
    ODocument vDocA_db1 = database1.newInstance();
    vDocA_db1.field(NAME, "docA");
    database1.save(vDocA_db1);

    // Create docB.
    ODocument vDocB_db1 = database1.newInstance();
    vDocB_db1.field(NAME, "docB");
    database1.save(vDocB_db1);

    database1.commit();

    // Keep the IDs.
    ORID vDocA_Rid = vDocA_db1.getIdentity().copy();
    ORID vDocB_Rid = vDocB_db1.getIdentity().copy();

    ORecordVersion vDocA_version = OVersionFactory.instance().createUntrackedVersion();
    ORecordVersion vDocB_version = OVersionFactory.instance().createUntrackedVersion();

    database2.begin(TXTYPE.OPTIMISTIC);
    try {
      // Get docA and update in db2 transaction context
      ODocument vDocA_db2 = database2.load(vDocA_Rid);
      vDocA_db2.field(NAME, "docA_v2");
      database2.save(vDocA_db2);

      // Concurrent update docA via database1 -> will throw OConcurrentModificationException at
      // database2.commit().
      database1.begin(TXTYPE.OPTIMISTIC);
      try {
        vDocA_db1.field(NAME, "docA_v3");
        database1.save(vDocA_db1);
        database1.commit();
      } catch (OConcurrentModificationException e) {
        Assert.fail("Should not failed here...");
      }
      Assert.assertEquals(vDocA_db1.field(NAME), "docA_v3");
      // Keep the last versions.
      // Following updates should failed and reverted.
      vDocA_version = vDocA_db1.getRecordVersion();
      vDocB_version = vDocB_db1.getRecordVersion();

      // Update docB in db2 transaction context -> should be rollbacked.
      ODocument vDocB_db2 = database2.load(vDocB_Rid);
      vDocB_db2.field(NAME, "docB_UpdatedInTranscationThatWillBeRollbacked");
      database2.save(vDocB_db2);

      // Will throw OConcurrentModificationException
      database2.commit();
      Assert.fail("Should throw OConcurrentModificationException");
    } catch (OConcurrentModificationException e) {
      database2.rollback();
    }

    // Force reload all (to be sure it is not a cache problem)
    database1.close();
    database2.getStorage().close();
    database2 = new ODatabaseDocumentTx(url).open("admin", "admin");

    ODocument vDocA_db2 = database2.load(vDocA_Rid);
    Assert.assertEquals(vDocA_db2.field(NAME), "docA_v3");
    Assert.assertEquals(vDocA_db2.getRecordVersion(), vDocA_version);

    // docB should be in the first state : "docB"
    ODocument vDocB_db2 = database2.load(vDocB_Rid);
    Assert.assertEquals(vDocB_db2.field(NAME), "docB");
    Assert.assertEquals(vDocB_db2.getRecordVersion(), vDocB_version);

    database1.close();
    database2.close();
  }