<div dir="ltr">I understood what you said but didn't communicate my suggestion clearly enough sorry.<div><br></div><div><span style="font-size:12.8px">System1 creates a new transaction</span></div><div>System1 registers a synchronization SYNC1 on transaction to record soon to be pending request for System2 *** NEW BIT<br style="font-size:12.8px"><span style="font-size:12.8px">System1 invokes EJB1 on System2 with XID1</span><br style="font-size:12.8px"><span style="font-size:12.8px">System2 examines EJB1's transaction mode</span><br style="font-size:12.8px"><span style="font-size:12.8px">System2 inflows XID1</span><br style="font-size:12.8px"><span style="font-size:12.8px">System2 executes EJB1</span><br style="font-size:12.8px"><span style="font-size:12.8px">System2 returns with "EnlistMe" flag</span></div><div>System1 updates SYNC1 to say the call returned *** NEW BIT<br style="font-size:12.8px"><span style="font-size:12.8px">System1 enlists System2</span><br style="font-size:12.8px"><span style="font-size:12.8px">...other work happens...</span><br style="font-size:12.8px"><span style="font-size:12.8px">System1 prepares XID1</span><br style="font-size:12.8px"><span style="font-size:12.8px">System2 prepares XID1 & returns XA_OK</span><br style="font-size:12.8px"><span style="font-size:12.8px">System1 commits</span><br style="font-size:12.8px"><span style="font-size:12.8px">System2 commits</span><br></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">If the failure happens before EJB1 returns then SYNC1 throws an exception during beforeCompletion.</span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 9 February 2016 at 16:50, David M. Lloyd <span dir="ltr"><<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think you misunderstood what I"m getting at. Consider this normal sequence of events under the proposed enlistment strategy:<br>
<br>
System1 creates a new transaction<br>
System1 invokes EJB1 on System2 with XID1<br>
System2 examines EJB1's transaction mode<br>
System2 inflows XID1<br>
System2 executes EJB1<br>
System2 returns with "EnlistMe" flag<br>
System1 enlists System2<br>
...other work happens...<br>
System1 prepares XID1<br>
System2 prepares XID1 & returns XA_OK<br>
System1 commits<br>
System2 commits<br>
<br>
Now what happens if the System1-System2 connection is broken before EJB1 returns? System2 is never enlisted, System1 may prepare & commit the XID1 transaction without ever knowing about System2, which now has an orphaned transaction which has performed some unknown amount of work under the same GTID as the now-committed transaction. System2's transaction times out, the work is rolled back, and chaos ensues.<br>
<br>
So this means that I have to have System2 tell System1 to enlist *before* "System2 executes EJB1" rather than after, right?<div class="HOEnZb"><div class="h5"><br>
<br>
On 02/09/2016 10:41 AM, Tom Jenkinson wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
My understanding would be that the EJB transport would detect the<br>
transaction.commit call (although it should have an outstanding EJB call so<br>
I don't think that it would be possible for a client to call commit) and<br>
throw an exception. It could be that EJB transport would register a<br>
synchronization beforeCompletion to do this.<br>
<br>
On 9 February 2016 at 14:41, David M. Lloyd <<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I have a follow-up question about delaying enlistment (I'm getting to this<br>
point in the code).<br>
<br>
I'm worried about a scenario wherein the subordinate server begins the<br>
transaction, does some work in the EJB, and then tries to return, but the<br>
connection to the server has been partitioned indefinitely. The server<br>
*may* opt to continue and commit the transaction despite the subordinate<br>
failure, in which case the subordinate, not receiving any control messages<br>
from the root coordinator, would roll back the transaction at the timeout,<br>
while the server (not knowing about the subordinate server) would continue<br>
and commit the transaction, not knowing what work (if any) the subordinate<br>
server had performed.<br>
<br>
Is this a real problem? Perhaps I do need an "enlist me" callback to the<br>
server after all, which executes before the EJB imports and resumes the<br>
subordinate transaction?<br>
<br>
<br>
On 02/02/2016 08:27 AM, Tom Jenkinson wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
No problem :)<br>
<br>
On 2 February 2016 at 13:49, David M. Lloyd <<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a>><br>
wrote:<br>
<br>
Ah okay, cool. This is an easy (and, in hindsight, rather obvious)<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
enhancement that I can build into the new protocol with a minimum of<br>
effort.<br>
<br>
Thanks!<br>
<br>
On 02/02/2016 03:01 AM, Tom Jenkinson wrote:<br>
<br>
Hi David,<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I was referring to case 1 when the transaction is inflowed into a second<br>
server. For JTS the type of transaction we create is a<br>
ServerTopLevelAction and this in its ctor calls back to the remote<br>
server:<br>
<br>
<br>
<a href="https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/interposition/resources/arjuna/ServerTopLevelAction.java#L121" rel="noreferrer" target="_blank">https://github.com/jbosstm/narayana/blob/master/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/interposition/resources/arjuna/ServerTopLevelAction.java#L121</a><br>
If the transport can do that without the TMs assistance then that works<br>
for me :)<br>
<br>
I don't think we should optimize for case 2. The incidents where a<br>
transaction is created and not used should be really low.<br>
<br>
Thanks,<br>
Tom<br>
<br>
<br>
<br>
On 1 February 2016 at 15:43, David M. Lloyd <<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a><br>
<mailto:<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a>>> wrote:<br>
<br>
I was thinking about this a bit. It seems to me that there are two<br>
"levels" of this that could be explored:<br>
<br>
1. A transaction was made available to the server, but the EJB on<br>
the server does not use the caller's transaction context, so the<br>
EJB<br>
code never actually has to inflow the transaction. The EJB code<br>
would be able to make this determination without any help from the<br>
TM.<br>
<br>
2. A transaction was made available, and the EJB resumed it, but no<br>
resources were actually enlisted, or perhaps resources were<br>
enlisted<br>
but not actually used, resulting in the same effect but relying on<br>
the TM to provide this information.<br>
<br>
I guess when you refer to a callback from Narayana, (2) is what<br>
you're referring to? When would this information be available?<br>
Maybe as some special result of suspending the transaction?<br>
<br>
<br>
On 01/29/2016 12:27 PM, David M. Lloyd wrote:<br>
<br>
That's an interesting idea. So in effect, the remote EJB would<br>
tell the<br>
caller "you sent me a transaction ID, but in the end, I didn't<br>
use it"?<br>
I would need to think about how this might work in the<br>
presence of<br>
multiple concurrent invocations on the same transaction.<br>
<br>
Either way though, I think it would still be beneficial for<br>
clients to<br>
be able to explicitly annotate a client method (or otherwise<br>
establish a<br>
policy) such that it causes transactions to be propagated (or<br>
not), or<br>
to enforce transaction-related preconditions. The interceptor<br>
that<br>
implements this feature doesn't actually have protocol<br>
awareness:<br>
it<br>
just examines the current environment, and decides whether to<br>
attach the<br>
transaction to the invocation context.<br>
<br>
On 1/29/16 10:42 AM, Tom Jenkinson wrote:<br>
<br>
One option that I would favour is to go down the JTS route<br>
where the<br>
subordinate calls back on the parent to tell it to register<br>
it in the<br>
transaction. This could be a new JBoss Remoting API that I<br>
can invoke<br>
from Narayana. The call would not necessarily be a remote<br>
call, it would<br>
invoke back into the JBR transport to tell it that when it<br>
returns to<br>
the parent it needs to enlist (or not).<br>
<br>
On 29 January 2016 at 15:47, David M. Lloyd<br>
<<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a> <mailto:<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a>><br>
<mailto:<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a><br>
<br>
<mailto:<a href="mailto:david.lloyd@redhat.com" target="_blank">david.lloyd@redhat.com</a>>>> wrote:<br>
<br>
As you may know, WildFly supports a feature wherein an<br>
EJB client<br>
which<br>
is invoking an EJB on a remote server has the option<br>
to<br>
propagate its<br>
local transaction to the remote server, treating the<br>
remote server<br>
as a<br>
subordinate and coordinating the transaction's<br>
two-phase commit among<br>
the resultant graph of servers. This feature has<br>
always been<br>
limited in<br>
that, when enabled, transactions are always<br>
propagated,<br>
regardless of<br>
the peer EJB's transaction policy, or of whether the<br>
peer even has a<br>
transaction manager.<br>
<br>
So, for the invocation rework which I anticipate will<br>
be included in<br>
WildFly 11, I've introduced a new client-side<br>
annotation intended<br>
to be<br>
associated with the EJB interface which informs the<br>
client library<br>
what<br>
to do for transaction propagation for that interface.<br>
In addition, I<br>
intend to configuration strategies which will allow<br>
the<br>
default<br>
mode to<br>
be specified in various ways (per-thread, globally,<br>
and<br>
by target<br>
interface/method all come to mind), for cases where<br>
the<br>
EJB's remote<br>
interface cannot be easily modified for some reason.<br>
I<br>
expect to<br>
also<br>
broaden these configuration strategies to apply to all<br>
client-side<br>
EJB<br>
interface/methods configuration items [3].<br>
<br>
The first part of this change is the addition of a new<br>
annotation<br>
called<br>
@ClientTransaction [1], which accepts as a value an<br>
enum called<br>
ClientTransactionPolicy [2]. The latter specifies<br>
whether a local<br>
transaction is required or forbidden for the method or<br>
interface, and<br>
also specifies whether the transaction is propagated<br>
or<br>
not<br>
propagated.<br>
<br>
I've added copious amounts of JavaDoc in order to<br>
establish<br>
exactly what<br>
the behavior of each mode is, as well as to specify<br>
how<br>
each mode<br>
interacts with the various modules that are configured<br>
via the<br>
standard<br>
javax.ejb.TransactionAttributeType enum.<br>
<br>
[1]<br>
<br>
<br>
<br>
<a href="https://github.com/jbossas/jboss-ejb-client/blob/master/src/main/java/org/jboss/ejb/client/annotation/ClientTransaction.java" rel="noreferrer" target="_blank">https://github.com/jbossas/jboss-ejb-client/blob/master/src/main/java/org/jboss/ejb/client/annotation/ClientTransaction.java</a><br>
<br>
[2]<br>
<br>
<br>
<br>
<a href="https://github.com/jbossas/jboss-ejb-client/blob/master/src/main/java/org/jboss/ejb/client/annotation/ClientTransactionPolicy.java" rel="noreferrer" target="_blank">https://github.com/jbossas/jboss-ejb-client/blob/master/src/main/java/org/jboss/ejb/client/annotation/ClientTransactionPolicy.java</a><br>
<br>
[2] (raw)<br>
<br>
<br>
<br>
<a href="https://raw.githubusercontent.com/jbossas/jboss-ejb-client/master/src/main/java/org/jboss/ejb/client/annotation/ClientTransactionPolicy.java" rel="noreferrer" target="_blank">https://raw.githubusercontent.com/jbossas/jboss-ejb-client/master/src/main/java/org/jboss/ejb/client/annotation/ClientTransactionPolicy.java</a><br>
<br>
[3] for a list, see:<br>
<br>
<br>
<br>
<a href="https://github.com/jbossas/jboss-ejb-client/tree/master/src/main/java/org/jboss/ejb/client/annotation" rel="noreferrer" target="_blank">https://github.com/jbossas/jboss-ejb-client/tree/master/src/main/java/org/jboss/ejb/client/annotation</a><br>
<br>
<br>
--<br>
- DML<br>
_______________________________________________<br>
wildfly-dev mailing list<br>
<a href="mailto:wildfly-dev@lists.jboss.org" target="_blank">wildfly-dev@lists.jboss.org</a><br>
<mailto:<a href="mailto:wildfly-dev@lists.jboss.org" target="_blank">wildfly-dev@lists.jboss.org</a>><br>
<mailto:<a href="mailto:wildfly-dev@lists.jboss.org" target="_blank">wildfly-dev@lists.jboss.org</a><br>
<mailto:<a href="mailto:wildfly-dev@lists.jboss.org" target="_blank">wildfly-dev@lists.jboss.org</a>>><br>
<a href="https://lists.jboss.org/mailman/listinfo/wildfly-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/wildfly-dev</a><br>
<br>
<br>
<br>
<br>
<br>
--<br>
- DML<br>
<br>
<br>
<br>
--<br>
</blockquote>
- DML<br>
<br>
<br>
</blockquote>
<br>
</blockquote>
--<br>
- DML<br>
<br>
</blockquote>
<br>
</blockquote>
<br></div></div><span class="HOEnZb"><font color="#888888">
-- <br>
- DML<br>
</font></span></blockquote></div><br></div>