<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">
<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>
                                <td>
                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="https://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>
                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
Bridging WS-BA to JTA
</h3>
<span style="margin-bottom: 10px;">
created by <a href="https://community.jboss.org/people/paul.robinson">Paul Robinson</a> in <i>JBoss Transactions Development</i> - <a href="https://community.jboss.org/message/794318#794318">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">
<div class="jive-rendered-content"><p>This is a design descusion for how to implement <a class="jive-link-external-small" href="https://issues.jboss.org/browse/JBTM-1099" rel="nofollow">[JBTM-1099]</a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span>Consider the following, common, use case for <span>WS</span>-<span>BA</span>:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span>A <span>WS</span>-<span>BA</span> enabled service offers an operation for doing some work. For example, making a booking or purchasing an item. When this operation is invoked a new order is committed to the database. If the business activity is later canceled, the compensate operation is invoked on the service. This compensation action will take the necessary steps to undo the work and will likely make changes to the database content. For example by deleting the order or marking it as canceled. Alternatively, if the activity is successful the 'close' operation will be invoked on the service as a confirmation. It's also possible that the service may make an update to the database here, to mark the order as confirmed.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span>Two of the key benefits of using <span>WS</span>-<span>BA</span> in this scenario are that; <span>i</span>) no locks are held between the <span>doWork</span> and close/compensate phases, and ii) the service is guaranteed to receive the outcome of the activity even in the presence of failures. </span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>If the service wants to update the database within a transaction, they have these options (that I can currently come up with, there may be others):</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><h4><span>Manage a single subordinate <span>JTA</span> transaction (Poor choice)</span></h4><p><span>Here the service would begin a subordinate <span>JTA</span> transaction in the <span>'doWork'</span> method, prepare it during <span>'confirmCompleted'</span>, and then commit it during the 'close' or rollback during the 'compensate'. Essentially the application is mapping the <span>WS</span>-<span>BA</span> lifecycle onto a 2PC ACID lifecycle.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>The main problems with this approach are that:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><ol><li><span>Locks are held between the two phases of the protocol. Violates <span>i</span>) from above.</span></li><li>It's tricky/error-prone for the developer as they need to manage a subordinate transaction.</li><li>There are failure windows which violate ii) from above.</li></ol><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><h4><span>Use multiple <span>JTA</span> transactions  (Better choice, but not perfect)</span></h4><p><span>Here the application begins a transaction at the start of the <span>doWork</span> method and commits it just before the method returns. A separate <span>JTA</span> transaction is begun at the start of the close/compensate method and committed just before it returns. This approach is more likely to be used than the previous as it can be achieved with just <span>JPA</span> and transactional annotations. On the surface it looks like it should just work. However I think it is susceptible to a failure window:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><h6 style="text-align: start;">Failure window in first phase</h6><p style="text-align: start;">Consider the following scenario:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><ol><li><span>Client begins a <span>BA</span></span></li><li>Client invokes service</li><li><span>Service begins a <span>JTA</span> transaction</span></li><li>Service updates the DB</li><li><span>Service commits the <span>JTA</span></span></li><li>Service crashes</li><li><span>Service resumes and does nothing as the <span>BA</span> did not progress far enough to produce a log</span></li><li><span>Client receives a failure from the service invocation and either cancels the <span>BA</span> or attempts to close it; which the coordinator will fail as the participant did not complete.</span></li></ol><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="text-align: start;"><span>Here the <span>BA</span> was unsuccessful, but the <span>JTA</span> transaction committed. We have an inconsistent state.</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><h6 style="text-align: start;">No failure window in the second phase</h6><p style="text-align: start;"><span>I don't think failure windows exists for the close or compensate methods. This is because these methods are invoked after a log has been written and so survive failure. They are also invoked periodically until the coordinator receives an acknowledgement. For this to work, the application logic needs to tolerate retries; which is the case for plain <span>WS</span>-<span>BA</span> anyway. Consider this example:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><ol><li>Coordinator sends 1st compensate message</li><li>Compensate invoked for 1st time (C1)</li><li>C1 begins JTA1</li><li>C1 reads from the DB to check not compensated (Obtains a read lock)</li><li>C1 discovers that not yet compensated so writes the change to the DB to do the compensate (Obtains write lock)</li><li><span>Coordinator sends 2nd compensate message as it has not <span>recived</span> the <span>ack</span> to the firs tin a timely manor</span></li><li>Compensate is invoked for the 2nd time (C2)</li><li>C2 begins JTA2</li><li>C2 reads form DB to check not compensated (Waits to obtain the read lock)</li><li>C1 commits JTA1</li><li><span>First compensate message is <span>acked</span></span></li><li>C2 now obtains the read lock on the data and discovers that already compensated</li><li>C2 commits JTA2</li><li><span>Second compensate message is <span>acked</span>.</span></li></ol><p><span style="text-align: start;"><span>Providing the same transaction is used to do both; <span>i</span>) detect compensation, and ii) compensate; I believe we are safe.</span></span></p><h5 style="text-align: start;">Potential Solution</h5><p><span style="text-align: start;"><span>In this solution we configure an interceptor on the service request that automatically enlists a participant in the incoming <span>WS</span>-<span>BA</span> activity and maps the events onto calls to a subordinate <span>JTA</span> transaction. This is a similar approach to that used for <span>WS</span>-AT to <span>JTA</span> mapping. This is the mapping that I propose:</span></span></p><table border="1" cellpadding="3" cellspacing="0" class="jiveBorder" height="233" style="border: 1px solid #000000; width: 859px;"><tbody><tr><th align="center" style="border:1px solid black;border: 1px solid #000000;background-color: #6690bc;" valign="middle"><span style="color: #ffffff;"><strong><span><span>WS</span>-<span>BA</span></span><br/></strong></span></th><th align="center" style="border:1px solid black;border: 1px solid #000000;background-color: #6690bc;" valign="middle"><span style="color: #ffffff;"><strong><span><span>JTA</span></span><br/></strong></span></th></tr><tr><td style="border:1px solid black;border: 1px solid #000000;">Application request arrives</td><td style="border:1px solid black;border: 1px solid #000000;">Begin subordinate JTA1</td></tr><tr><td style="border:1px solid black;border: 1px solid #000000;">completed</td><td style="border:1px solid black;border: 1px solid #000000;"><span>Prepare  JTA1 (ensures that we can later complete. Notify <span>'cannotComplete'</span> if JTA1 fails to prepare)</span></td></tr><tr><td style="border:1px solid black;border: 1px solid #000000;"><span><span>confirmCompleted</span></span></td><td style="border:1px solid black;border: 1px solid #000000;">Commit  JTA1</td></tr><tr><td style="border:1px solid black;border: 1px solid #000000;">close  arrives</td><td style="border:1px solid black;border: 1px solid #000000;"><span>begin  JTA2 and <span>asociate</span> with thread that calls 'close' on the <span>WS</span>-<span>BA</span> participant</span></td></tr><tr><td style="border:1px solid black;border: 1px solid #000000;">closed leaves</td><td style="border:1px solid black;border: 1px solid #000000;"><span>commit JTA2. Failure here will cause the <span>'close'to</span> be retried.</span></td></tr><tr><td style="border:1px solid black;border: 1px solid #000000;">compensate arrives</td><td style="border:1px solid black;border: 1px solid #000000;"><span>begin  JTA2 and <span>asociate</span> with thread that calls 'compensate' on the <span>WS</span>-<span>BA</span> participant</span></td></tr><tr><td style="border:1px solid black;border: 1px solid #000000;">compensated leaves</td><td style="border:1px solid black;border: 1px solid #000000;">commit JTA2. Failure here will cause the compensate to retry.</td></tr></tbody></table><p>The crux of the solution is:</p><ol><li><span>Don't commit JTA1 until the transaction log has been written. Do this by delaying the commit until the <span>confirmCompleted</span> event is raised.</span></li><li><span>'Surround' the calls to the close and compensate invocations on the <span>WS</span>-<span>BA</span> participant with JTA2. I don't think this can be done through the <span>XTS</span> <span>API</span>, so would require some internal changes.</span></li></ol><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><h4 style="text-align: start;">Feedback Please!</h4><p>Feedback on this issue would be much appreciated. </p></div>
<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
<p style="margin: 0;">Reply to this message by <a href="https://community.jboss.org/message/794318#794318">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in JBoss Transactions Development at <a href="https://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2041">Community</a></p>
</div></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>