-
45. Re: Can resource delisting prevent participation in commit processing?
dmlloyd Jun 4, 2018 9:05 AM (in response to jhalliday)jhalliday wrote:
Well once the dust settles on the Jakarta EE transition I'm hopeful things will be able to move along at a less slothful pace, but yes, we may be able to crank out a proprietary solution more quickly than waiting on the spec.
In general I'm leaning towards a design decoupling the ordering hint from the lifecycle transition. A giveMeAnOrderingHint method should be called by the TM on the resource, at a point in time between the final 'end' and the 'prepare', but not mutate the resource state the way either of those do. The resource implementation may use 'end' to populate its client-side state cache so it can answer the giveMeAnOrderingHint question efficiently, but that's an implementation detail. The downside is that this doesn't provide for grouping end+prepare operations to save an additional round trip, but it's got a lot less opportunity for messing up the state lifecycle management and error handling that has traditionally been a thorny area for the TM.
Sure this works for me. Would the ordering hint be per-resource or per-RM?
-
46. Re: Can resource delisting prevent participation in commit processing?
jhalliday Jun 4, 2018 9:20 AM (in response to dmlloyd)per-resource, if only because isSameRM is broken in weird and wonderful ways on many drivers. My fav is the one that does string comparison on the connection url, so can't cope with e.g. hostname aliases...
-
47. Re: Can resource delisting prevent participation in commit processing?
tomjenkinson Jun 5, 2018 9:48 AM (in response to jhalliday)So to summarise the idea is that before 2PC but after all "xa_end" calls are made we ask the resources if they want to be called "first". In theory the ones that assume they will be RDONLY will respond yes, the others would respond "no" (or "yes" if they want to be mean and scupper the optimization)?
Did I parse this right?
-
48. Re: Can resource delisting prevent participation in commit processing?
jhalliday Jun 5, 2018 9:57 AM (in response to tomjenkinson)yes I think that's right as far as David's requirements are concerned. The DB vs JMS ordering problem that gave rise to JTA-4 is more difficult, since it needs to distinguish between a XA_OK JMS and and XA_OK DB, both of which would respond 'no'. We may need e.g. the return type to be a structure with additional data that the JTA can use when ordering them, or to establish some conventions e.g. an enum with defined ordering or a number range with some defined constants.
As far as the patch goes, I'd be inclined to do it in two passes: the groundwork to refactor the lifecycle so arjunacore drives xa end as a separate phase; then the ordering stuff. The first of those parts could go in now, though it would not be immediately useful. The second needs us to pin down the ordering API and semantics, with or without input from the spec process.
-
49. Re: Can resource delisting prevent participation in commit processing?
tomjenkinson Jun 5, 2018 10:09 AM (in response to jhalliday)Thanks Jonathan, ochaloup - does that work for you too?
I agree it might need some further ordering encoding in there (maybe a class name or numeric order as we have discussed before I expect). If Ondra does a refactor of the xa_end now and also extends the design doc he has shared with some ideas on the ordering options. We can then go to the spec committee with the concept but also have a proof of concept (for EJB only until we determine if it will go into spec, so keep in an .internal. package for now).
-
50. Re: Can resource delisting prevent participation in commit processing?
dmlloyd Jun 5, 2018 10:10 AM (in response to jhalliday)jhalliday wrote:
per-resource, if only because isSameRM is broken in weird and wonderful ways on many drivers. My fav is the one that does string comparison on the connection url, so can't cope with e.g. hostname aliases...
Would the resource implementation still be required to perform the aforementioned optimization (wherein only the last one queried would return XA_OK, with the rest returning XA_RDONLY) in order to avoid a 2PC? Or would the TM be able to use its isSameRM knowledge in order to know that it's a 1PC even if multiple (isSameRM) resources return XA_OK?
-
51. Re: Can resource delisting prevent participation in commit processing?
tomjenkinson Jun 5, 2018 10:14 AM (in response to dmlloyd)Unless it is a problem I would think it best that normal XA rules for the resources. This would just guarantee you could order the ones that are going to return RDONLY to be called first.
-
52. Re: Can resource delisting prevent participation in commit processing?
tomjenkinson Jun 5, 2018 10:17 AM (in response to tomjenkinson)A small point is that 2PC should not (IMO) halt if you can't xa_commit an nth resource.
i.e
// ask resources for their order NEW PHASES
// xa_prepare in order (assume they are all XA_OK, so not really using the new feature
// Go into commit
xa_commit(1)
xa_commit(2)
xa_commit(3) // comm failure
still:
xa_commit(4)If we were being strict we should probably not do xa_commit(4) until xa_commit(3) was sucessful I expect. We could make strict ordering an option but it is better as a hint I think.
-
53. Re: Can resource delisting prevent participation in commit processing?
jhalliday Jun 5, 2018 10:20 AM (in response to dmlloyd)> would the TM be able to use its isSameRM knowledge in order to know that it's a 1PC even if multiple (isSameRM) resources return XA_OK
The spec doesn't really allow it to. It calls the resource operations once per branch (i.e. XAResource instance) not once per RM, because the state machine is defined per-branch, not per-RM. It's theoretically possible for an RM to return OK from one branch but ROLLBACK from another, for example if the work in one branch's scope caused a conflict and the other didn't. Likewise in phase two a branch can throw a heuristic whilst its sibling in the same RM doesn't. The optimization has to come from the RM side.
-
54. Re: Can resource delisting prevent participation in commit processing?
dmlloyd Jun 5, 2018 10:31 AM (in response to jhalliday)jhalliday wrote:
> would the TM be able to use its isSameRM knowledge in order to know that it's a 1PC even if multiple (isSameRM) resources return XA_OK
The spec doesn't really allow it to. It calls the resource operations once per branch (i.e. XAResource instance) not once per RM, because the state machine is defined per-branch, not per-RM. It's theoretically possible for an RM to return OK from one branch but ROLLBACK from another, for example if the work in one branch's scope caused a conflict and the other didn't. Likewise in phase two a branch can throw a heuristic whilst its sibling in the same RM doesn't. The optimization has to come from the RM side.
OK. Does this then mean that if the new feature is implemented in terms of a separate query method, we can count on that method being called no more than one time per resource?
-
55. Re: Can resource delisting prevent participation in commit processing?
jhalliday Jun 5, 2018 10:38 AM (in response to dmlloyd)I'd envisaged a XAResource.getOrderingHint() to have regular getter semantics - it's a read-only method on the object that should return the same thing if called multiple times. It's categorically not a state change operation like end or prepare. Best implementation guess, the xa_end (or the first hint call, if lazy) sets some internal state in the resource that the ordering hint refers to. Whilst in normal operation the TM should indeed only need to call it once, I don't really like the idea of a getter that will blow up if invoked multiple times. We'd probably want to rename it to reflect that if it's necessary. Are you implying it's tricky to implement in way that allows multiple calls?
-
56. Re: Can resource delisting prevent participation in commit processing?
dmlloyd Jun 5, 2018 10:58 AM (in response to jhalliday)jhalliday wrote:
I'd envisaged a XAResource.getOrderingHint() to have regular getter semantics - it's a read-only method on the object that should return the same thing if called multiple times. It's categorically not a state change operation like end or prepare. Best implementation guess, the xa_end (or the first hint call, if lazy) sets some internal state in the resource that the ordering hint refers to. Whilst in normal operation the TM should indeed only need to call it once, I don't really like the idea of a getter that will blow up if invoked multiple times. We'd probably want to rename it to reflect that if it's necessary. Are you implying it's tricky to implement in way that allows multiple calls?
Well, I'm not sure yet TBH. It gets a bit hard to preserve state when resources are serialized. I'm not sure I can properly make the optimization and also have this method be idempotent; more research is required.
Hopefully it's not a practical problem though as we try to only enlist one time per subordinate.
-
57. Re: Can resource delisting prevent participation in commit processing?
jhalliday Jun 5, 2018 11:03 AM (in response to dmlloyd)hmm. When are they getting serialized? Is that for the client-server transport, or for the transaction log? There is a narrow window of time in which it's valid for the TM to invoke getOrderingHint - specifically between all resources being ended and the first being prepared/committed. Outside of that it could reasonably e.g. throw IllegalStateException. You'd need state for the optimization anyhow, since you'd need to track which one is returning OK whilst the others do the RDONLY trick?
-
58. Re: Can resource delisting prevent participation in commit processing?
dmlloyd Jun 5, 2018 11:14 AM (in response to jhalliday)jhalliday wrote:
hmm. When are they getting serialized? Is that for the client-server transport, or for the transaction log? There is a narrow window of time in which it's valid for the TM to invoke getOrderingHint - specifically between all resources being ended and the first being prepared/committed. Outside of that it could reasonably e.g. throw IllegalStateException. You'd need state for the optimization anyhow, since you'd need to track which one is returning OK whilst the others do the RDONLY trick?
This would be for the transaction log. We already handle serialization though: in this case we always return XA_OK from "prepare". So I guess we could probably do the same thing (and use the same code) internally for getOrderingHint.
-
59. Re: Can resource delisting prevent participation in commit processing?
jhalliday Jun 5, 2018 11:41 AM (in response to dmlloyd)I'm not hugely worried about preserving idempotent behavior across serialization boundaries, since it's not likely to be used anyhow. I think it's reasonable to just cop out with an IllegalStateException or e.g. return Hint.NO_PREFERENCE in that case. I'm more concerned that having a non-idempotent getter violates the 'no surprise' rule for API design on the in-memory object instance. As far as possible it should be stable if the resource state doesn't change. It can (and should) change return value if the actual prepare result doesn't match the previously hinted one. The ordering hint is a suggestion, not a firm promise. The TM may ignore it, or the RM may get it wrong or not provide it. Best-effort will suffice - in harder cases we just fall back to the unoptimized order.
To my mind it's the choice of initial value that's tricky, rather than remembering/repeating it once it's decided. That's because although each branch (resource instance) has its own xa state machine, the underlying implementation is really one state machine per-tx, shared by all branches. The optimization with N-1 RDONLY + 1 OK branch in the same RM is essentially a case of having N-1 of the per-resource state machines working as stubs, whilst the other passes through to the real transaction state machine. At some point you need to choose which resource is the special case, then get the others to behave accordingly. So the state underpinning the hint is not strictly local to the resource instance, but the result of a collective decision across all the resources for the RM. The hint value may therefore change, even though the resource state (at least in terms of the xa state machine lifecycle) doesn't. That's why I think it may better to just throw an exception if invoked too early i.e. whilst other branches of the tx for which isSameRM==true are still not ended.