package org.tests.transaction; import io.ebean.BaseTestCase; import io.ebean.Ebean; import io.ebean.EbeanServer; import io.ebean.Transaction; import io.ebean.annotation.Transactional; import org.tests.model.m2m.MnyB; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; public class TestCommitAndContinue extends BaseTestCase { private static final Logger logger = LoggerFactory.getLogger("org.avaje.ebean.TXN"); @Test @Transactional public void transactional_partialSuccess() { MnyB a = new MnyB("a100"); MnyB b = new MnyB("b200"); a.save(); // commit at this point Ebean.currentTransaction().commitAndContinue(); try { b.save(); // some error occurs throw new IllegalStateException(); } catch (IllegalStateException e) { // mark the transaction as rollback Ebean.currentTransaction().setRollbackOnly(); // use a different transaction to assert EbeanServer server = Ebean.getDefaultServer(); Transaction anotherTxn = server.createTransaction(); // success prior to commitAndContinue assertNotNull(server.find(MnyB.class, a.getId(), anotherTxn)); // insert failed after commitAndContinue assertNull(server.find(MnyB.class, b.getId(), anotherTxn)); } } /** * The @Transactional is nicer to me. */ @Test public void tryFinally_partialSuccess() { MnyB a = new MnyB("a100"); MnyB b = new MnyB("b200"); EbeanServer server = Ebean.getDefaultServer(); Transaction txn = server.beginTransaction(); try { a.save(); // commit at this point txn.commitAndContinue(); try { b.save(); // some error occurs throw new IllegalStateException(); } catch (IllegalStateException e) { // mark the transaction as rollback txn.setRollbackOnly(); // use a different transaction to assert Transaction anotherTxn = server.createTransaction(); // success prior to commitAndContinue assertNotNull(server.find(MnyB.class, a.getId(), anotherTxn)); // insert failed after commitAndContinue assertNull(server.find(MnyB.class, b.getId(), anotherTxn)); } // does not commit due to the txn.setRollbackOnly(); txn.commit(); } finally { server.endTransaction(); } } @Test @Transactional public void transactional_partialSuccess_secondTransactionInsert() { MnyB a = new MnyB("a100"); MnyB b = new MnyB("b200"); MnyB c = new MnyB("c300"); a.save(); // commit at this point Ebean.currentTransaction().commitAndContinue(); try { b.save(); // some error occurs throw new IllegalStateException(); } catch (IllegalStateException e) { // mark the transaction as rollback Ebean.currentTransaction().setRollbackOnly(); // use a different transaction to do something useful EbeanServer server = Ebean.getDefaultServer(); Transaction txn2 = server.createTransaction(); try { server.save(c, txn2); txn2.commit(); } finally { txn2.end(); } } // asserts EbeanServer server = Ebean.getDefaultServer(); Transaction txnForAssert = server.createTransaction(); // success prior to commitAndContinue assertNotNull(server.find(MnyB.class, a.getId(), txnForAssert)); // insert failed after commitAndContinue assertNull(server.find(MnyB.class, b.getId(), txnForAssert)); // successful insert using txn2 assertNotNull(server.find(MnyB.class, c.getId(), txnForAssert)); } @Test public void basic() { MnyB a = new MnyB("a"); MnyB b = new MnyB("b"); MnyB c = new MnyB("c"); Transaction txn = Ebean.beginTransaction(); try { a.save(); txn.commitAndContinue(); txn.setBatchMode(true); b.save(); logger.info("... pre commitAndContinue"); txn.commitAndContinue(); c.save(); txn.commit(); } finally { txn.end(); } } @Test @Transactional public void runTransactional() { new MnyB("a100").save(); new MnyB("a101").save(); Ebean.currentTransaction().commitAndContinue(); new MnyB("a200").save(); new MnyB("a201").save(); } }