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(); }