Skip to content

Instantly share code, notes, and snippets.

@gytis
Last active July 26, 2016 09:13
Show Gist options
  • Save gytis/5cd80619cb829689025d648a7f6e7772 to your computer and use it in GitHub Desktop.
Save gytis/5cd80619cb829689025d648a7f6e7772 to your computer and use it in GitHub Desktop.
Compensating transaction in JTA
class Service {
@Inject
EntityManager entityManager;
@Inject
CompensationManager compensationManager;
@Inject
Session session; // E.g. Neo4j session
@Transactional // Begins a JTA transaction
@Compensatable // Begins a compensating transaction
void method() {
// Enlists compensations XA resource to the JTA transaction
// Somehow lets @Compensatable interceptor know to not complete compensating transaction
compensationManager.joinJtaTransaction();
entityManager.persist("...");
CompensatableAction
// Registers work action and its compensating action
.addWork(() -> session.run("<< Write to the db >>"), () -> session.run("<< Undo what you've wrote >>"))
// Executes work and enlists participant with compensating action to the compensating transaction
.execute();
}
}
class CompensationsXAResource implements XAResource, LastResource {
int prepare(Xid xid) {
return XA_OK;
}
void commit(Xid xid, boolean b) {
try {
BAControllerFactory.getInstance().completeBusinessActivity(false);
} catch (Exception e) {
throw new XAException(XAException.XA_RBROLLBACK);
}
}
void rollback(Xid xid) {
try {
BAControllerFactory.getInstance().cancelBusinessActivity();
} catch (Exception e) {
throw new XAException(XAException.XA_RBROLLBACK);
}
}
// The rest of XAResource methods
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment