#287 - ENH: Support nested transactions with the Ebean.beginTransaction() API

This commit is contained in:
rbygrave
2015-05-08 21:55:49 +12:00
parent fc3e1083d7
commit f7fa778e99
10 changed files with 726 additions and 21 deletions
@@ -338,6 +338,11 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return null;
}
@Override
public Transaction beginTransaction(TxScope scope) {
return null;
}
@Override
public Transaction beginTransaction(TxIsolation isolation) {
return null;
@@ -0,0 +1,58 @@
package com.avaje.tests.transaction;
import com.avaje.ebean.*;
import com.avaje.tests.model.basic.Country;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Product;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestNestedBeginRequired extends BaseTestCase {
Logger logger = LoggerFactory.getLogger(TestNestedBeginRequired.class);
EbeanServer server = Ebean.getServer(null);
@Test
public void test() {
someOuterMethod();
}
private void someOuterMethod() {
Transaction txn = server.beginTransaction(TxScope.required());
try {
server.find(Country.class).findRowCount();
someInnerMethod();
server.find(Product.class).findRowCount();
txn.commit();
} finally {
txn.end();
}
}
private void someInnerMethod() {
logger.debug("someInnerMethod() ...");
Transaction txn = server.beginTransaction(TxScope.required());
try {
server.find(Customer.class).findRowCount();
txn.commit();
} finally {
txn.end();
}
logger.debug("someInnerMethod() ... done");
}
}
@@ -0,0 +1,70 @@
package com.avaje.tests.transaction;
import com.avaje.ebean.*;
import com.avaje.tests.model.basic.*;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestNestedBeginRequiredWithFailure extends BaseTestCase {
Logger logger = LoggerFactory.getLogger(TestNestedBeginRequiredWithFailure.class);
EbeanServer server = Ebean.getServer(null);
@Test
public void test() {
someOuterMethod();
}
private void someOuterMethod() {
Transaction txn = server.beginTransaction(TxScope.required());
try {
server.find(Country.class).findRowCount();
try {
someInnerMethodWithFailure();
server.find(Product.class).findRowCount();
txn.commit();
} catch (RuntimeException e) {
logger.info("Inner method failed with " + e);
}
} finally {
// For REQUIRED ... the transaction can already been
// rolled back (by inner method) so that case is expected
// (and that is the case here - txn is already rolled back)
txn.end();
}
}
private void someInnerMethodWithFailure() {
logger.debug("someInnerMethod() ...");
Transaction txn = server.beginTransaction(TxScope.required());
try {
server.find(Customer.class).findRowCount();
EBasic basic = new EBasic();
basic.setName("ignore");
server.save(basic);
if (server != null) {
throw new RuntimeException("barf");
}
txn.commit();
} finally {
txn.end();
logger.debug("someInnerMethod() ... done");
}
}
}
@@ -0,0 +1,57 @@
package com.avaje.tests.transaction;
import com.avaje.ebean.*;
import com.avaje.tests.model.basic.Country;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Product;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestNestedBeginRequiresNew extends BaseTestCase {
Logger logger = LoggerFactory.getLogger(TestNestedBeginRequiresNew.class);
EbeanServer server = Ebean.getServer(null);
@Test
public void test() {
someOuterMethod();
}
private void someOuterMethod() {
Transaction txn = server.beginTransaction(TxScope.requiresNew());
try {
server.find(Country.class).findRowCount();
someInnerMethod();
server.find(Product.class).findRowCount();
txn.commit();
} finally {
txn.end();
}
}
private void someInnerMethod() {
logger.debug("someInnerMethod() ...");
Transaction txn = server.beginTransaction(TxScope.requiresNew());
try {
server.find(Customer.class).findRowCount();
txn.commit();
} finally {
txn.end();
}
logger.debug("someInnerMethod() ... done");
}
}
@@ -0,0 +1,63 @@
package com.avaje.tests.transaction;
import com.avaje.ebean.*;
import com.avaje.tests.model.basic.Country;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Product;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestNestedBeginRequiresNewWithFailure extends BaseTestCase {
Logger logger = LoggerFactory.getLogger(TestNestedBeginRequiresNewWithFailure.class);
EbeanServer server = Ebean.getServer(null);
@Test
public void test() {
someOuterMethod();
}
private void someOuterMethod() {
Transaction txn = server.beginTransaction(TxScope.requiresNew());
try {
server.find(Country.class).findRowCount();
try {
someInnerMethodWithFailure();
} catch (RuntimeException e) {
logger.info("Inner method failed with " + e.getMessage());
}
server.find(Product.class).findRowCount();
txn.commit();
} finally {
txn.end();
}
}
private void someInnerMethodWithFailure() {
logger.debug("someInnerMethod() ...");
Transaction txn = server.beginTransaction(TxScope.requiresNew());
try {
server.find(Customer.class).findRowCount();
if (server != null) {
throw new RuntimeException("barf");
}
txn.commit();
} finally {
txn.end();
}
logger.debug("someInnerMethod() ... done");
}
}