[New] Added TransactionCloseStrategy.DO_NOTHING
- added a new closing strategy which is now the default closing strategy. This effectively makes a new transaction read only
This commit is contained in:
parent
1736435864
commit
85b82f6628
|
@ -115,34 +115,26 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
this.commands = new ArrayList<>();
|
this.commands = new ArrayList<>();
|
||||||
this.flushedCommands = new ArrayList<>();
|
this.flushedCommands = new ArrayList<>();
|
||||||
this.lockedElements = new HashSet<>();
|
this.lockedElements = new HashSet<>();
|
||||||
this.closeStrategy = TransactionCloseStrategy.ROLLBACK;
|
this.closeStrategy = TransactionCloseStrategy.DO_NOTHING;
|
||||||
this.txResult = new TransactionResult(getRealmName(), System.nanoTime(), new Date());
|
this.txResult = new TransactionResult(getRealmName(), System.nanoTime(), new Date());
|
||||||
this.txResult.setState(TransactionState.OPEN);
|
this.txResult.setState(TransactionState.OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen() {
|
public TransactionState getState() {
|
||||||
return this.txResult.getState() == TransactionState.OPEN;
|
return this.txResult.getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRollingBack() {
|
public boolean isRollingBack() {
|
||||||
return this.txResult.getState() == TransactionState.ROLLING_BACK;
|
return this.txResult.getState().isRollingBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCommitting() {
|
public boolean isCommitting() {
|
||||||
return this.txResult.getState() == TransactionState.COMMITTING;
|
return this.txResult.getState().isCommitting();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean isClosing() {
|
||||||
public boolean isCommitted() {
|
return this.txResult.getState().isClosing();
|
||||||
return this.txResult.getState() == TransactionState.COMMITTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRolledBack() {
|
|
||||||
return this.txResult.getState() == TransactionState.ROLLED_BACK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,6 +151,11 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
return certificate;
|
return certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransactionCloseStrategy getCloseStrategy() {
|
||||||
|
return this.closeStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
private void setCloseStrategy(TransactionCloseStrategy closeStrategy) {
|
private void setCloseStrategy(TransactionCloseStrategy closeStrategy) {
|
||||||
this.closeStrategy = closeStrategy;
|
this.closeStrategy = closeStrategy;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +165,11 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
this.closeStrategy.close(this);
|
this.closeStrategy.close(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doNothingOnClose() {
|
||||||
|
setCloseStrategy(TransactionCloseStrategy.DO_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commitOnClose() {
|
public void commitOnClose() {
|
||||||
setCloseStrategy(TransactionCloseStrategy.COMMIT);
|
setCloseStrategy(TransactionCloseStrategy.COMMIT);
|
||||||
|
@ -551,19 +553,80 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void autoCloseableDoNothing() throws StrolchTransactionException {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
try {
|
||||||
|
this.txResult.setState(TransactionState.CLOSING);
|
||||||
|
|
||||||
|
if (!this.commands.isEmpty()) {
|
||||||
|
String msg = "Current close strategy {0} is readonly and thus does not support doing commands!";
|
||||||
|
msg = MessageFormat.format(msg, this.closeStrategy);
|
||||||
|
throw fail(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
long auditTrailDuration = writeAuditTrail();
|
||||||
|
|
||||||
|
// rollback and release any resources
|
||||||
|
rollback(this.txResult);
|
||||||
|
|
||||||
|
handleDoNothing(start, auditTrailDuration);
|
||||||
|
this.txResult.setState(TransactionState.CLOSED);
|
||||||
|
} catch (Exception e) {
|
||||||
|
handleFailure(start, e);
|
||||||
|
this.txResult.setState(TransactionState.FAILED);
|
||||||
|
} finally {
|
||||||
|
releaseElementLocks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void writeChanges(TransactionResult txResult) throws Exception;
|
protected abstract void writeChanges(TransactionResult txResult) throws Exception;
|
||||||
|
|
||||||
protected abstract void rollback(TransactionResult txResult) throws Exception;
|
protected abstract void rollback(TransactionResult txResult) throws Exception;
|
||||||
|
|
||||||
protected abstract void commit() throws Exception;
|
protected abstract void commit() throws Exception;
|
||||||
|
|
||||||
|
private void handleDoNothing(long start, long auditTrailDuration) {
|
||||||
|
|
||||||
|
long end = System.nanoTime();
|
||||||
|
long txDuration = end - this.txResult.getStartNanos();
|
||||||
|
long closeDuration = end - start;
|
||||||
|
|
||||||
|
this.txResult.setTxDuration(txDuration);
|
||||||
|
this.txResult.setCloseDuration(closeDuration);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("TX user=");
|
||||||
|
sb.append(this.certificate.getUsername());
|
||||||
|
|
||||||
|
sb.append(", realm="); //$NON-NLS-1$
|
||||||
|
sb.append(getRealmName());
|
||||||
|
|
||||||
|
sb.append(", took="); //$NON-NLS-1$
|
||||||
|
sb.append(StringHelper.formatNanoDuration(txDuration));
|
||||||
|
|
||||||
|
sb.append(", action=");
|
||||||
|
sb.append(this.action);
|
||||||
|
|
||||||
|
if (closeDuration >= 100000000L) {
|
||||||
|
sb.append(", close="); //$NON-NLS-1$
|
||||||
|
sb.append(StringHelper.formatNanoDuration(closeDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAuditTrailEnabled() && auditTrailDuration >= 100000000L) {
|
||||||
|
sb.append(", auditTrail="); //$NON-NLS-1$
|
||||||
|
sb.append(StringHelper.formatNanoDuration(auditTrailDuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private void handleCommit(long start, long auditTrailDuration, long observerUpdateDuration) {
|
private void handleCommit(long start, long auditTrailDuration, long observerUpdateDuration) {
|
||||||
|
|
||||||
long end = System.nanoTime();
|
long end = System.nanoTime();
|
||||||
long txDuration = end - this.txResult.getStartNanos();
|
long txDuration = end - this.txResult.getStartNanos();
|
||||||
long closeDuration = end - start;
|
long closeDuration = end - start;
|
||||||
|
|
||||||
this.txResult.setState(TransactionState.COMMITTED);
|
|
||||||
this.txResult.setTxDuration(txDuration);
|
this.txResult.setTxDuration(txDuration);
|
||||||
this.txResult.setCloseDuration(closeDuration);
|
this.txResult.setCloseDuration(closeDuration);
|
||||||
|
|
||||||
|
@ -603,7 +666,6 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
||||||
long txDuration = end - this.txResult.getStartNanos();
|
long txDuration = end - this.txResult.getStartNanos();
|
||||||
long closeDuration = end - start;
|
long closeDuration = end - start;
|
||||||
|
|
||||||
this.txResult.setState(TransactionState.ROLLED_BACK);
|
|
||||||
this.txResult.setTxDuration(txDuration);
|
this.txResult.setTxDuration(txDuration);
|
||||||
this.txResult.setCloseDuration(closeDuration);
|
this.txResult.setCloseDuration(closeDuration);
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,20 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
*/
|
*/
|
||||||
public PersistenceHandler getPersistenceHandler();
|
public PersistenceHandler getPersistenceHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently set {@link TransactionCloseStrategy}
|
||||||
|
*
|
||||||
|
* @return the currently set {@link TransactionCloseStrategy}
|
||||||
|
*/
|
||||||
|
public TransactionCloseStrategy getCloseStrategy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT CALL THIS METHOD. If the currently set close strategy is {@link TransactionCloseStrategy#DO_NOTHING}, then
|
||||||
|
* when the transaction is closed, this method is called no changes to the model is performed but locks on objects
|
||||||
|
* are released and any other resources are released
|
||||||
|
*/
|
||||||
|
public void autoCloseableDoNothing() throws StrolchTransactionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DO NOT CALL THIS METHOD. If the currently set close strategy is {@link TransactionCloseStrategy#COMMIT}, then
|
* DO NOT CALL THIS METHOD. If the currently set close strategy is {@link TransactionCloseStrategy#COMMIT}, then
|
||||||
* when the transaction is closed, this method is called and all registered {@link Command} are performed, locks on
|
* when the transaction is closed, this method is called and all registered {@link Command} are performed, locks on
|
||||||
|
@ -166,6 +180,11 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
@Override
|
@Override
|
||||||
public void close() throws StrolchTransactionException;
|
public void close() throws StrolchTransactionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link TransactionCloseStrategy} to {@link TransactionCloseStrategy#DO_NOTHING}
|
||||||
|
*/
|
||||||
|
public void doNothingOnClose();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link TransactionCloseStrategy} to {@link TransactionCloseStrategy#COMMIT}
|
* Sets the {@link TransactionCloseStrategy} to {@link TransactionCloseStrategy#COMMIT}
|
||||||
*/
|
*/
|
||||||
|
@ -198,29 +217,26 @@ public interface StrolchTransaction extends AutoCloseable {
|
||||||
public void flush();
|
public void flush();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the transaction is still open, i.e. not being closed or rolling back, committing, etc.
|
* @return the current state of the transaction
|
||||||
|
*
|
||||||
|
* @see TransactionState
|
||||||
*/
|
*/
|
||||||
public boolean isOpen();
|
public TransactionState getState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the transaction is in the process of rolling back all changes
|
* @return if the current state of the {@link StrolchTransaction} is {@link TransactionState#ROLLING_BACK}
|
||||||
*/
|
*/
|
||||||
public boolean isRollingBack();
|
public boolean isRollingBack();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the transaction is in the process of committing the changes
|
* @return if the current state of the {@link StrolchTransaction} is {@link TransactionState#COMMITTING}
|
||||||
*/
|
*/
|
||||||
public boolean isCommitting();
|
public boolean isCommitting();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return if the transaction has committed all changes
|
* @return if the current state of the {@link StrolchTransaction} is {@link TransactionState#CLOSING}
|
||||||
*/
|
*/
|
||||||
public boolean isCommitted();
|
public boolean isClosing();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return if the transaction has rolled back all changes
|
|
||||||
*/
|
|
||||||
public boolean isRolledBack();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the given argument is true, then no observer updates are performed
|
* If the given argument is true, then no observer updates are performed
|
||||||
|
|
|
@ -17,16 +17,68 @@ package li.strolch.persistence.api;
|
||||||
|
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines what happens when a {@link StrolchTransaction} is closed. Strolch transactions are auto closeable which means
|
||||||
|
* when used in a try-with-resource block, then they are automatically closed. Depending on the use case, these
|
||||||
|
* transactions might write something to the DB, or only read the model, or even have to roll back, this is controlled
|
||||||
|
* by using these enums.
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
public enum TransactionCloseStrategy {
|
public enum TransactionCloseStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This is for read only transactions. If this strategy is used, then no changes will be written to the model. Use
|
||||||
|
* {@link StrolchTransaction#doNothingOnClose()} to simply close the transaction, releasing any resources
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b> When using this strategy, then the transaction will throw exceptions if you try to add commands to
|
||||||
|
* the transaction.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
DO_NOTHING() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close(StrolchTransaction tx) throws StrolchException {
|
||||||
|
tx.autoCloseableDoNothing();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main close strategy type where changes are written to the model. Use
|
||||||
|
* {@link StrolchTransaction#commitOnClose()} to commit any changes i.e. commands added to the transaction
|
||||||
|
*/
|
||||||
COMMIT() {
|
COMMIT() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(StrolchTransaction tx) throws StrolchException {
|
public void close(StrolchTransaction tx) throws StrolchException {
|
||||||
tx.autoCloseableCommit();
|
tx.autoCloseableCommit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In exceptional cases one might not want any changes to be written to the model, thus calling
|
||||||
|
* {@link StrolchTransaction#rollbackOnClose()} will have the transaction roll back all changes
|
||||||
|
*/
|
||||||
ROLLBACK() {
|
ROLLBACK() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close(StrolchTransaction tx) throws StrolchException {
|
public void close(StrolchTransaction tx) throws StrolchException {
|
||||||
tx.autoCloseableRollback();
|
tx.autoCloseableRollback();
|
||||||
|
@ -34,4 +86,6 @@ public enum TransactionCloseStrategy {
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract void close(StrolchTransaction tx) throws StrolchException;
|
public abstract void close(StrolchTransaction tx) throws StrolchException;
|
||||||
|
|
||||||
|
public abstract boolean isReadonly();
|
||||||
}
|
}
|
|
@ -15,11 +15,39 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.persistence.api;
|
package li.strolch.persistence.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The different states of a {@link StrolchTransaction}
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
public enum TransactionState {
|
public enum TransactionState {
|
||||||
OPEN, //
|
OPEN, //
|
||||||
|
CLOSING, //
|
||||||
COMMITTING, //
|
COMMITTING, //
|
||||||
ROLLING_BACK, //
|
ROLLING_BACK, //
|
||||||
|
CLOSED, //
|
||||||
COMMITTED, //
|
COMMITTED, //
|
||||||
ROLLED_BACK,
|
ROLLED_BACK,
|
||||||
FAILED;
|
FAILED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this is {@link #ROLLING_BACK}
|
||||||
|
*/
|
||||||
|
public boolean isRollingBack() {
|
||||||
|
return this == ROLLING_BACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this is {@link #COMMITTING}
|
||||||
|
*/
|
||||||
|
public boolean isCommitting() {
|
||||||
|
return this == COMMITTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this is {@link #CLOSING}
|
||||||
|
*/
|
||||||
|
public boolean isClosing() {
|
||||||
|
return this == CLOSING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
package li.strolch.service;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import li.strolch.command.AddResourceCommand;
|
||||||
|
import li.strolch.model.ModelGenerator;
|
||||||
|
import li.strolch.model.Order;
|
||||||
|
import li.strolch.model.Resource;
|
||||||
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
import li.strolch.service.api.AbstractService;
|
||||||
|
import li.strolch.service.api.ServiceArgument;
|
||||||
|
import li.strolch.service.api.ServiceResult;
|
||||||
|
import li.strolch.service.test.AbstractRealmServiceTest;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ch.eitchnet.utils.dbc.DBC;
|
||||||
|
|
||||||
|
public class TxTest extends AbstractRealmServiceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldCommit() {
|
||||||
|
|
||||||
|
runServiceInAllRealmTypes(CommitService.class, new ServiceArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRollback() {
|
||||||
|
|
||||||
|
runServiceInAllRealmTypes(RollbackService.class, new ServiceArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldDoNothing() {
|
||||||
|
|
||||||
|
runServiceInAllRealmTypes(ReadonlyService.class, new ServiceArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotAllowCommandsOnDoNothibg() {
|
||||||
|
|
||||||
|
runServiceInAllRealmTypes(ReadonlyFailService.class, new ServiceArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CommitService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult getResultInstance() {
|
||||||
|
return new ServiceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||||
|
|
||||||
|
String id = "flushSuccessfully";
|
||||||
|
Resource resource = ModelGenerator.createResource(id, id, id);
|
||||||
|
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
|
||||||
|
DBC.PRE.assertNull("Did not expect resource with id " + id, tx.getResourceBy(id, id));
|
||||||
|
|
||||||
|
AddResourceCommand addResCmd = new AddResourceCommand(getContainer(), tx);
|
||||||
|
addResCmd.setResource(resource);
|
||||||
|
tx.addCommand(addResCmd);
|
||||||
|
tx.flush();
|
||||||
|
DBC.PRE.assertNotNull("Expected resource with id " + id, tx.getResourceBy(id, id));
|
||||||
|
|
||||||
|
tx.commitOnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now make sure the new resource exists
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
|
||||||
|
Resource res = tx.getResourceBy(id, id);
|
||||||
|
if (res == null) {
|
||||||
|
throw tx.fail("Did not expect resource with id " + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServiceResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RollbackService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult getResultInstance() {
|
||||||
|
return new ServiceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||||
|
|
||||||
|
String id = "flushSuccessfully";
|
||||||
|
Resource resource = ModelGenerator.createResource(id, id, id);
|
||||||
|
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
|
||||||
|
DBC.PRE.assertNull("Did not expect resource with id " + id, tx.getResourceBy(id, id));
|
||||||
|
|
||||||
|
AddResourceCommand addResCmd = new AddResourceCommand(getContainer(), tx);
|
||||||
|
addResCmd.setResource(resource);
|
||||||
|
tx.addCommand(addResCmd);
|
||||||
|
tx.flush();
|
||||||
|
DBC.PRE.assertNotNull("Expected resource with id " + id, tx.getResourceBy(id, id));
|
||||||
|
|
||||||
|
tx.rollbackOnClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// now make sure the new resource does not exist
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
|
||||||
|
Resource res = tx.getResourceBy(id, id);
|
||||||
|
if (res != null) {
|
||||||
|
throw tx.fail("Did not find expected resource with id " + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServiceResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ReadonlyService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult getResultInstance() {
|
||||||
|
return new ServiceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||||
|
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
Resource yellowBall = tx.getResourceBy("Ball", "yellow");
|
||||||
|
assertNotNull("Expected to find the yellow ball", yellowBall);
|
||||||
|
|
||||||
|
Order myCarOrder = tx.getOrderBy("ProductionOrder", "myCarOrder");
|
||||||
|
assertNotNull("Expected to find the my car order", myCarOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServiceResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ReadonlyFailService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult getResultInstance() {
|
||||||
|
return new ServiceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||||
|
|
||||||
|
String id = "flushSuccessfully";
|
||||||
|
Resource resource = ModelGenerator.createResource(id, id, id);
|
||||||
|
|
||||||
|
boolean txFailed = false;
|
||||||
|
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||||
|
AddResourceCommand addResCmd = new AddResourceCommand(getContainer(), tx);
|
||||||
|
addResCmd.setResource(resource);
|
||||||
|
tx.addCommand(addResCmd);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
txFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue("TX should have failed!", txFailed);
|
||||||
|
|
||||||
|
return ServiceResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue