-
1. Re: Possible improvements to Compensations API
tomjenkinson Mar 27, 2015 7:38 AM (in response to gytis)Gytis Trikleris wrote:
Exposing public API to register handlers. Currently the only supported way to register the handler is to use annotations. However, this is limited to having one handler per java method.
Good observation - maybe this will be a less of an issue with https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
I agree being able to set more than one behavior per business logic would be useful. Would these all execute in the same compensating transaction - I imagine they would.
For JSE <8 we can either go the route of the public API (where would propose adding the method) or we could go down supporting @TxCompensate with a class[], e.g.:
@TxCompensate(handlers={UndoCredit.class,UndoDebit.class})
I rather prefer the public API as it might be nice to add handlers at runtime?
-
2. Re: Possible improvements to Compensations API
tomjenkinson Mar 27, 2015 7:46 AM (in response to gytis)Gytis Trikleris wrote:
- Providing a way to pass data to the specific handler. We have a way to store compensation scoped data. However, it is accessible by every handler. It would be beneficial to pass some specific data to the particular handler, e.g. updated mongo document, which might have to be compensated.
This also seems like a good idea. I guess at the moment you could do this with multiple javabeans that wrap smaller abouts of data.
In the business logic:
@Inject
DocumentNameHolder documentNameHolder;
The compensation scoped object
@CompensationScoped
public class DocumentNameHolder {
public String documentName;
}
Maybe you could do something like.
In the business logic:
@CompensationScopedData(id="DocumentNameHolder")
String documentName;
Then refer to it in in the compensation handler:
@CompensationScopedData(id="DocumentNameHolder")
String documentName;
That might be quite usable. At the moment the struct-like @CompensationScoped does seem like it could be a bit clunky.
-
3. Re: Possible improvements to Compensations API
gytis Mar 27, 2015 7:58 AM (in response to tomjenkinson)Repeatable @TxCompensate would certainly be useful.
However, this wouldn't solve all the problems. Imagine scenario with mongo from the patent:
@Compensatable
@TxCompensate(SharedCompensationHandler.class)
@TxConfirm(SharedConfirmationHandler.class)
public void transferMoney(String fromAccount, String toAccount, Double amount) {
...
accountsCollection.updateOne(debitUpdateFilter, debitDocument);
accountsCollection.updateOne(creditUpdateFilter, creditDocument);
...
}
In this case you'd have to options. The one displayed is having one compensation/confirmation handler for both update operations. Or if the operations are more complicated you could move each operation to separate methods and assign separate handlers.
However, with additional API this could be possible:
@Compensatable
public void transferMoney(String fromAccount, String toAccount, Double amount) {
...
accountsCollection.updateOne(debitUpdateFilter, debitDocument);
compensations.addCompensationHandler(DebitCompensationHandler.class)
compensations.addCompensationHandler(DebitConfirmationHandler.class)
accountsCollection.updateOne(creditUpdateFilter, creditDocument);
compensations.addCompensationHandler(CreditCompensationHandler.class)
compensations.addCompensationHandler(CreditConfirmationHandler.class)
...
}
Additionally, could be useful to pass same extra data to each add* method for that handler.
-
4. Re: Possible improvements to Compensations API
tomjenkinson Mar 27, 2015 8:05 AM (in response to gytis)Gytis Trikleris wrote:
Repeatable @TxCompensate would certainly be useful.
However, this wouldn't solve all the problems. Imagine scenario with mongo from the patent:
@Compensatable
@TxCompensate(SharedCompensationHandler.class)
@TxConfirm(SharedConfirmationHandler.class)
public void transferMoney(String fromAccount, String toAccount, Double amount) {
...
accountsCollection.updateOne(debitUpdateFilter, debitDocument);
accountsCollection.updateOne(creditUpdateFilter, creditDocument);
...
}
In this case you'd have to options. The one displayed is having one compensation/confirmation handler for both update operations. Or if the operations are more complicated you could move each operation to separate methods and assign separate handlers.
However, with additional API this could be possible:
@Compensatable
public void transferMoney(String fromAccount, String toAccount, Double amount) {
...
accountsCollection.updateOne(debitUpdateFilter, debitDocument);
compensations.addCompensationHandler(DebitCompensationHandler.class)
compensations.addCompensationHandler(DebitConfirmationHandler.class)
accountsCollection.updateOne(creditUpdateFilter, creditDocument);
compensations.addCompensationHandler(CreditCompensationHandler.class)
compensations.addCompensationHandler(CreditConfirmationHandler.class)
...
}
Additionally, could be useful to pass same extra data to each add* method for that handler.
Personally, I think you were right in that scenario to recommend moving the debit and crediting to separate business logics with separate handlers. But I an open to adding via an API being useful in some circumstances.
As a side note, in your example above "accountsCollection" is not linked in any way to "compensations.addCompensationHandler(DebitCompensationHandler.class)" that I can see.
-
5. Re: Possible improvements to Compensations API
gytis Mar 27, 2015 9:24 AM (in response to tomjenkinson)I understand that in this case the best way to go would be to split the logic, but I wanted to make a simple example. Actually, we spoke about this splitting with paul.robinson a couple of weeks ago, maybe he'll contribute some ideas to here too.
In the example accountsCollection is an instance of MongoCollection. However, debitDocument and creditDocument should be liked somehow with the respective handlers.