17.1. Using Web Services Atomic Transactions
This section describes how to use Web services atomic
transactions to enable interoperability with other external
transaction processing systems.
17.1.1. Overview of Web Services Atomic Transactions
Web services enable interoperability with other external
transaction processing systems, such as WebLogic, Websphere,
JBoss, Microsoft .NET, and so on, through the support of the
following specifications:
Web Services Atomic Transaction
(WS-AtomicTransaction) Versions 1.0, 1.1 and 1.2:
http://docs.oasis-open.org/ws-tx/wstx-wsat-1.2-spec-cs-01/wstx-wsat-1.2-spec-cs-01.html
Web Services Coordination (WS-Coordination) Versions
1.0, 1.1 and 1.2:
http://docs.oasis-open.org/ws-tx/wstx-wscoor-1.2-spec-cs-01/wstx-wscoor-1.2-spec-cs-01.html
These specifications define an extensible framework for
coordinating distributed activities among a set of participants.
The coordinator, shown in the following figure, is the central
component, managing the transactional state (coordination context)
and enabling Web services and clients to register as
participants.
The following table describes the components of Web services
atomic transactions, shown in the previous figure.
Table 17.1. Components of Web Services Atomic Transactions
Component
|
Description
|
---|
Coordinator
|
Manages the transactional state (coordination
context) and enables Web services and clients to
register as participants.
|
Activation Service
|
Enables the application to activate a
transaction and create a coordination context for an
activity. Once created, the coordination context is
passed with the transaction flow.
|
Registration Service
|
Enables an application to register as a
participant.
|
Application Protocol X, Y
|
Supported coordination protocols, such as
WS-AtomicTransaction.
|
The following figure shows two server instances interacting
within the context of a Web services atomic transaction.
Please note the following:
Using the local Jakarta Transactions transaction manager, a
transaction can be imported to or exported from the local
Jakarta Transactions environment as a subordinate transaction, all within
the context of a Web service request.
Creation and management of the coordination context
is handled by the local Jakarta Transactions transaction manager.
All transaction integrity management and recovery
processing is done by the local Jakarta Transactions transaction
manager.
The following describes a sample end-to-end Web services
atomic transaction interaction:
Application A begins a transaction on the current
thread of control using the Jakarta Transactions transaction manager on
Server A.
Application A calls a Web service method in
Application B on Server B.
Server A updates its transaction information and
creates a SOAP header that contains the coordination
context, and identifies the transaction and local
coordinator.
Server B receives the request for Application B,
detects that the header contains a transaction
coordination context and determines whether it has already
registered as a participant in this transaction. If it
has, that transaction is resumed and if not, a new
transaction is started.
Application B executes within the context of the
imported transaction. All transactional resources with
which the application interacts are enlisted with this
imported transaction.
Server B enlists itself as a participant in the
WS-AtomicTransaction transaction by registering with the
registration service indicated in the transaction
coordination context.
Server A resumes the transaction.
Application A resumes processing and commits the
transaction.
17.1.2. Enabling Web Services Atomic Transactions on Web Service
Endpoint
To enable Web services atomic transactions on a Web service
endpoint:
The following tables summarizes the configuration options
that you can set when enabling Web services atomic
transactions:
Table 17.2. Web Services Atomic Transactions Configuration
Options
Attribute
|
Description
|
---|
Version
|
Version of the Web services atomic transaction
coordination context that is used for Web services
and clients. For clients, it specifies the version
used for outbound messages only. The value specified
must be consistent across the entire
transaction.
Valid values include WSAT10 ,
WSAT11 , WSAT12 , and
DEFAULT . The DEFAULT value
for Web services is all three versions (driven by
the inbound request); the DEFAULT value
for Web service clients is
WSAT12 .
|
Flow type
|
Whether the Web services atomic transaction
coordination context is passed with the transaction
flow. See table for valid values.
|
The following table summarizes the valid values for flow
type and their meaning on the Web service and client. The table
also summarizes the valid value combinations when configuring web
services atomic transactions for an EJB-style web service that
uses the @TransactionAttribute
annotation.
Table 17.3. Flow Types Values
Value
|
Web Service Client
|
Web Service
|
Valid EJB @TransactionAttribute
Values
|
---|
NEVER
|
Jakarta Transactions transaction: Do not export transaction
coordination context.
No Jakarta Transactions transaction: Do not export transaction
coordination context.
|
Transaction flow exists: Do not import
transaction coordination context. If the
CoordinationContext header contains
mustunderstand="true" , a SOAP fault is
thrown.
No transaction flow: Do not import transaction
coordination context.
|
NEVER ,
NOT_SUPPORTED , REQUIRED ,
REQUIRES_NEW ,
SUPPORTS
|
SUPPORTS (Default)
|
Jakarta Transactions transaction: Export transaction
coordination context.
No Jakarta Transactions transaction: Do not export transaction
coordination context.
|
Transaction flow exists: Import transaction
context.
No transaction flow: Do not import transaction
coordination context.
|
REQUIRED ,
SUPPORTS
|
MANDATORY
|
Jakarta Transactions transaction: Export transaction
coordination context.
No Jakarta Transactions transaction: An exception is
thrown.
|
Transaction flow exists: Import transaction
context.
No transaction flow: Service-side exception is
thrown.
|
MANDATORY , REQUIRED ,
SUPPORTS
|
17.1.2.1. Using the @Transactional Annotation in Your JWS
File
To enable Web services atomic transactions, specify the
@com.sun.xml.ws.api.tx.at.Transactional
annotation on the Web service endpoint implementation class or
method.
If you specify the @Transactional
annotation at the Web service class level, the
settings apply to all two-way methods defined by the
service endpoint interface. You can override the flow
type value at the method level; however, the version
must be consistent across the entire
transaction.
You cannot explicitly specify the
@Transactional
annotation on a Web method
that is also annotated with
@Oneway
.
Web services atomic transactions cannot be used
with the client-side asynchronous programming
model.
The format for specifying the
@Transactional
annotation is as follows:
Example 17.1. @Transactional annotation format
@Transactional(
version=Transactional.Version.[WSAT10|WSAT11|WSAT12|DEFAULT],
value=Transactional.TransactionFowType.[MANDATORY|SUPPORTS|NEVER]
)
For more information about the version and flow type
configuration options, see Table.
The following sections provide examples of using the
@Transactional
annotation at the Web service
implementation class and method levels, and with the EJB
@TransactionAttribute annotation.
17.1.2.1.1. Example: Using @Transactional Annotation on a Web
Service Class
The following example shows how to add
@Transactional
annotation on a Web service
class. As shown in the example, there is an active Jakarta Transactions
transaction.
Example 17.2. @Transactional Annotation on a Web Service
Class
package examples.webservices.jaxws.wsat.simple.service;
. . .
import jakarta.transaction.UserTransaction;
. . .
import jakarta.jws.WebService;
import com.sun.xml.ws.api.tx.at.Transactional;
import com.sun.xml.ws.api.tx.at.Transactional.Version;
import com.sun.xml.ws.api.tx.at.Transactional.TransactionFlowType;
/**
* This JWS file forms the basis of a WS-Atomic Transaction Web Service
* with the
* operations: createAccount, deleteAccount, transferMonet, listAccount
*
*/
@WebService(serviceName = "WsatBankTransferService",
targetNamespace = "http://tempuri.org/",
portName = "WSHttpBindingIService")
@Transactional(value = Transactional.TransactionFlowType.MANDATORY,
version = com.sun.xml.ws.api.tx.at.Transactional.Version.WSAT10)
public class WsatBankTransferService {
public String createAccount(String acctNo, String amount) throws java
.lang.Exception {
Context ctx = null;
UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
try {
DataSource dataSource = (DataSource) ctx.lookup
("examples-demoXA-2");
String sql = "insert into wsat_acct_remote (acctno, " +
"amount) values (" + acctNo +
", " + amount + ")";
int insCount = dataSource.getConnection()
.prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at remote" +
".");
return ":acctno=" + acctNo + " amount=" + amount + " " +
"creating. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during " +
"createAccount() at remote.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}
public String deleteAccount(String acctNo) throws java.lang.Exception {
...
}
public String transferMoney(String acctNo, String amount,
String direction)
throws java.lang.Exception {
...
}
public String listAccount() throws java.lang.Exception {
...
}
}
17.1.2.1.2. Example: Using @Transactional Annotation on a Web
Service Method
The following example shows how to add
@Transactional
annotation on a Web service
implementation method.
Example 17.3. @Transactional Annotation on a Web Service
Method
package examples.webservices.jaxws.wsat.simple.service;
. . .
import jakarta.transaction.UserTransaction;
. . .
import jakarta.jws.WebService;
import com.sun.xml.ws.api.tx.at.Transactional;
import com.sun.xml.ws.api.tx.at.Transactional.Version;
import com.sun.xml.ws.api.tx.at.Transactional.TransactionFlowType;
/**
* This JWS file forms the basis of a WS-Atomic Transaction Web Service
* with the
* operations: createAccount, deleteAccount, transferMonet, listAccount
*
*/
@WebService(serviceName = "WsatBankTransferService",
targetNamespace = "http://tempuri.org/",
portName = "WSHttpBindingIService")
public class WsatBankTransferService {
@Transactional(value = Transactional.TransactionFlowType.MANDATORY,
version = com.sun.xml.ws.api.tx.at.Transactional.Version
.WSAT10)
public String createAccount(String acctNo, String amount) throws java
.lang.Exception {
Context ctx = null;
UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction) ctx.lookup("jakarta.transaction" + "" +
".UserTransaction");
try {
DataSource dataSource = (DataSource) ctx.lookup
("examples-demoXA-2");
String sql = "insert into wsat_acct_remote (acctno, " +
"amount) values (" + acctNo +
", " + amount + ")";
int insCount = dataSource.getConnection()
.prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at remote" +
".");
return ":acctno=" + acctNo + " amount=" + amount + " " +
"creating. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during " +
"createAccount() at remote.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}
public String deleteAccount(String acctNo) throws java.lang.Exception {
...
}
public String transferMoney(String acctNo, String amount,
String direction)
throws java.lang.Exception {
...
}
public String listAccount() throws java.lang.Exception {
...
}
}
17.1.2.1.3. Example: Using the @Transactional and the EJB
@TransactionAttribute Annotations Together
The following example illustrates how to use the
@Transactional
and EJB
@TransactionAttribute
annotations together.
In this case, the flow type values must be
compatible.
Example 17.4. @Transactional and the EJB
@TransactionAttribute Used Together
package examples.webservices.jaxws.wsat.simple.service;
. . .
import jakarta.transaction.UserTransaction;
. . .
import jakarta.jws.WebService;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import com.sun.xml.ws.api.tx.at.Transactional;
import com.sun.xml.ws.api.tx.at.Transactional.Version;
import com.sun.xml.ws.api.tx.at.Transactional.TransactionFlowType;
/**
* This JWS file forms the basis of a WS-Atomic Transaction Web Service
* with the
* operations: createAccount, deleteAccount, transferMonet, listAccount
*
*/
@WebService(serviceName = "WsatBankTransferService",
targetNamespace = "http://tempuri.org/",
portName = "WSHttpBindingIService")
@Transactional(value = Transactional.TransactionFlowType.MANDATORY,
version = com.sun.xml.ws.api.tx.at.Transactional.Version.WSAT10)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class WsatBankTransferService {
. . .
}
17.1.2.2. Enabling Web Services Atomic Transactions Starting From
WSDL
When enabled, Web services atomic transactions are
advertised in the WSDL file using a policy assertion.
This table summarizes the WS-AtomicTransaction 1.2
policy assertions that correspond to a set of common Web
services atomic transaction flow type and EJB Transaction
attribute combinations.
Web Services Atomic Transaction Policy Assertion Values
(WS-AtomicTransaction 1.2)
Table 17.4. Web Services Atomic Transaction Policy Assertion
Values (WS-AtomicTransaction 1.2)
Atomic Transaction Flow Type
|
EJB @TransactionAttribute
|
WS-AtomicTransaction 1.2 Policy
Assertion
|
---|
MANDATORY
|
MANDATORY , REQUIRED ,
SUPPORTS
|
<wsat:ATAssertion/>
|
SUPPORTS
|
REQUIRED ,
SUPPORTS
|
<wsat:ATAssertion
wsp:Optional="true"/>
|
NEVER
|
REQUIRED ,
REQUIRES_NEW , NEVER ,
SUPPORTS ,
NOT_SUPPORTED
|
No policy advertisement
|
17.1.3. Enabling Web Services Atomic Transactions on Web Service
Clients
On a Web service client, enable Web services atomic
transactions using one of the following methods:
Add the
@com.sun.xml.ws.api.tx.at.Transactional
annotation on the Web service reference injection point
for a client.
Pass the
com.sun.xml.ws.api.tx.at.TransactionalFeature
as a parameter when creating the Web service proxy or
dispatch.
At run-time, if the non-atomic transactional Web
service client calls an atomic transaction-enabled Web
service, then based on the flow type settings:
If the flow type is set to
SUPPORTS
or NEVER
on the
service-side, then the call is included as part of
the transaction.
If the flow type is set to
MANDATORY
, then an exception is
thrown.
17.1.3.1. Using @Transactional Annotation with the @WebServiceRef
Annotation
To enable Web services atomic transactions, specify the
@com.sun.xml.ws.api.tx.at.Transactional
annotation on the Web service client at the Web service
reference (@WebServiceRef
) injection
point.
See Using the @Transactional Annotation in Your JWS
File for the description of
@Transactional
annotation format.
The following example illustrates how to annotate the
Web service reference injection point. As shown in the
example, the active Jakarta Transactions transaction becomes a part of the
atomic transaction.
Example 17.5. Using @Transactional Annotation with the
@WebServiceRef Annotation
package examples.webservices.jaxws.wsat.simple.client;
. . .
import jakarta.servlet.*;
import jakarta.servlet.http.*;
. . .
import java.net.URL;
import javax.xml.namespace.QName;
import jakarta.transaction.UserTransaction;
import jakarta.transaction.SystemException;
import jakarta.xml.ws.WebServiceRef;
import com.sun.xml.ws.api.tx.at.Transactional;
*/
/**
* This example demonstrates using a WS-Atomic Transaction to create or
* delete an account,
* or transfer money via Web service as a single atomic transaction.
*/
public class WsatBankTransferServlet extends HttpServlet {
...
String url = "http://localhost:7001";
URL wsdlURL = new URL(url +
"/WsatBankTransferService/WsatBankTransferService");
...
DataSource ds = null;
UserTransaction utx = null;
try {
ctx = new InitialContext();
utx = (UserTransaction) ctx.lookup("jakarta.transaction" +
".UserTransaction");
utx.setTransactionTimeout(900);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
WsatBankTransferService port = getWebService(wsdlURL);
try {
utx.begin();
if (remoteAccountNo.length() > 0) {
if (action.equals("create")) {
result = port.createAccount(remoteAccountNo,
amount);
} else if (action.equals("delete")) {
result = port.deleteAccount(remoteAccountNo);
} else if (action.equals("transfer")) {
result = port.transferMoney(remoteAccountNo,
amount, direction);
}
}
utx.commit();
result = "The transaction is committed " + result;
} catch (java.lang.Exception e) {
try {
e.printStackTrace();
utx.rollback();
result = "The transaction is rolled back. " + e
.getMessage();
} catch (java.lang.Exception ex) {
e.printStackTrace();
result = "Exception is caught. Check stack trace.";
}
}
request.setAttribute("result", result);
...
@Transactional(value = Transactional.TransactionFlowType.MANDATORY,
version = Transactional.Version.WSAT10)
@WebServiceRef()
WsatBankTransferService_Service service;
private WsatBankTransferService getWebService() {
return service.getWSHttpBindingIService();
}
public String createAccount(String acctNo, String amount) throws
java.lang.Exception {
Context ctx = null;
UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction) ctx.lookup("jakarta.transaction" +
".UserTransaction");
try {
DataSource dataSource = (DataSource) ctx.lookup
("examples-dataSource-demoXAPool");
String sql = "insert into wsat_acct_local (acctno, " +
"amount) values (
" + acctNo + ", " + amount + ")";
int insCount = dataSource.getConnection()
.prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at " +
"local.");
return ":acctno=" + acctNo + " amount=" + amount + " " +
"creating.. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during " +
"createAccount() at local.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}
public String deleteAccount(String acctNo) throws java.lang.Exception {
...
}
public String transferMoney(String acctNo, String amount,
String direction)
throws java.lang.Exception {
...
}
public String listAccount() throws java.lang.Exception {
...
}
}
17.1.3.2. Passing the TransactionalFeature to the Client
To enable Web services atomic transactions on the client
of the Web service, you can pass the
com.sun.xml.ws.api.tx.at.TransactionalFeature
as
a parameter when creating the Web service proxy or dispatch,
as illustrated in the following example.
Example 17.6. Passing the TransactionalFeature to the
Client
package examples.webservices.jaxws.wsat.simple.client;
. . .
import jakarta.servlet.*;
import jakarta.servlet.http.*;
. . .
import java.net.URL;
import javax.xml.namespace.QName;
import jakarta.transaction.UserTransaction;
import jakarta.transaction.SystemException;
import com.sun.xml.ws.api.tx.at.TransactionalFeature;
import com.sun.xml.ws.api.tx.at.Transactional.Version;
import com.sun.xml.ws.api.tx.at.Transactional.TransactionFlowType;
*/
/**
* This example demonstrates using a WS-Atomic Transaction to create
* or delete an account,
* or transfer money via Web service as a single atomic transaction.
*/
public class WsatBankTransferServlet extends HttpServlet {
...
String url = "http://localhost:7001";
URL wsdlURL = new URL(url +
"/WsatBankTransferService/WsatBankTransferService");
...
DataSource ds = null;
UserTransaction utx = null;
try {
ctx = new InitialContext();
utx = (UserTransaction) ctx.lookup("jakarta.transaction" +
".UserTransaction");
utx.setTransactionTimeout(900);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
WsatBankTransferService port = getWebService(wsdlURL);
try {
utx.begin();
if (remoteAccountNo.length() > 0) {
if (action.equals("create")) {
result = port.createAccount(remoteAccountNo,
amount);
} else if (action.equals("delete")) {
result = port.deleteAccount(remoteAccountNo);
} else if (action.equals("transfer")) {
result = port.transferMoney(remoteAccountNo,
amount, direction);
}
}
utx.commit();
result = "The transaction is committed " + result;
} catch (java.lang.Exception e) {
try {
e.printStackTrace();
utx.rollback();
result = "The transaction is rolled back. " + e
.getMessage();
} catch (java.lang.Exception ex) {
e.printStackTrace();
result = "Exception is caught. Check stack trace.";
}
}
request.setAttribute("result", result);
...
// Passing the TransactionalFeature to the Client
private WsatBankTransferService getWebService(URL wsdlURL) {
TransactionalFeature feature = new TransactionalFeature();
feature.setFlowType(TransactionFlowType.MANDATORY);
feature.setVersion(Version.WSAT10);
WsatBankTransferService_Service service = new
WsatBankTransferService_Service(wsdlURL,
new QName("http://tempuri.org/",
"WsatBankTransferService"));
return service.getWSHttpBindingIService(new jakarta.xml.ws.soap
.AddressingFeature(), feature);
}
public String createAccount(String acctNo, String amount) throws
java.lang.Exception {
Context ctx = null;
UserTransaction tx = null;
try {
ctx = new InitialContext();
tx = (UserTransaction) ctx.lookup("jakarta.transaction" +
".UserTransaction");
try {
DataSource dataSource = (DataSource) ctx.lookup
("examples-dataSource-demoXAPool");
String sql = "insert into wsat_acct_local (acctno, " +
"amount) values (
" + acctNo + ", " + amount + ")";
int insCount = dataSource.getConnection()
.prepareStatement(sql).executeUpdate();
if (insCount != 1)
throw new java.lang.Exception("insert fail at " +
"local.");
return ":acctno=" + acctNo + " amount=" + amount + " " +
"creating.. ";
} catch (SQLException e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new SQLException("SQL Exception during " +
"createAccount() at local.");
}
} catch (java.lang.Exception e) {
System.out.println("**** Exception caught *****");
e.printStackTrace();
throw new java.lang.Exception(e);
}
}
public String deleteAccount(String acctNo) throws java.lang.Exception {
...
}
public String transferMoney(String acctNo, String amount,
String direction)
throws java.lang.Exception {
...
}
public String listAccount() throws java.lang.Exception {
...
}
}
17.1.4. System Level Configuration
To specify SSL be used for WS-AT protocol exchanges set the
wsat.ssl.enabled
system property to
true
, i.e. start the server with
-Dwsat.ssl.enabled=true
. The default value is
false
.
To disabled WS-AT transaction logging and recovery set the
wsat.recovery.enabled
system property to
false
, i.e. start the server with
-Dwsat.recovery.enabled=false
. The default value is
true
.
The WS-C and WS-AT endpoints necessary for WS-AT are
deployed only when the first web service is deployed to the
container. Therefore, it is necessary to have at least one web
service deployed to the target container for WS-AT to function
properly even in the case where only clients are used in the Metro
instance.
Compatibility between the Metro 2.1 and pre-2.1 (submission
version) WS-AT implementions is not supported.
17.2. About the basicWSTX Example
The basicWSTX example shows the following on the
client-side:
Developers use existing Jakarta Transactions APIs.
Invocations of transacted web service operations flow
transactional context from client to web service. Persistent
resources updated with client-created transactions are all
committed or rolled back as a single atomic
transaction.
After the client-side code commits or aborts the Jakarta Transactions
transaction, the client confirms that all operations in the
transaction succeeded or failed by using calls to
verify
methods on the transacted web
service.
SampleServiceClient
, a WSIT servlet that initiates
the transaction, and msclient
, a client that performs the
same operations but runs on the Microsoft side, both interact with the
following components running on the service-side:
SimpleService
, a web service implemented as
a Java servlet with transacted operations. The Edit Web
Service Attributes feature in the NetBeans IDE WSIT plug-in is
used to configure Transaction Attributes of each web service
operation.
SimpleServiceASCMTEJB
, a web service
implemented as container-managed transaction enterprise bean
(CMT EJB). No configuration is necessary for this case.
LibraryFacadeWebServiceBean
, a web service
that uses the Jakarta Persistence API with two JDBC
resources
Managed Jakarta EE resources participating in a distributed
transaction having its transacted updates all committed or
rolled back
The servlet and CMT EJB transacted web service
operations manipulate two Jakarta Messaging resources:
jms/ConnectionFactory
, an
XATransaction
connection factory
jms/Queue
, a Jakarta Messaging queue
The LibraryFacadeWebServiceBean
web service
operations manipulate the JDBC resources:
connectionPool
, an
XATransaction
JDBC connection pool
jdbc/javaProgrammingLibrary
, a JDBC
connection resource
This example shows how to use XATransaction
-enabled Jakarta Messaging and JDBC. The first version of this example, showing
WSIT-to-WSIT operations, has the SampleServiceClient
client configured to run on one GlassFish instance and the service
running on the other GlassFish instance. Either the Java client or the
Java web service could be replaced by a semantically equivalent
Microsoft implementation. The Java client is, in fact, replaced by a
Microsoft WCF client in the more advanced version of the
example.
With the SampleServiceClient
client, the
WS-Coordination/WS-AtomicTransaction protocol messages flow back and
forth between the two GlassFish instances just as they do in the
Microsoft-to-Sun transaction interoperability scenario with the
msclient
client.
The basicWSTX
example was initially designed so it
could be run in either one or in two GlassFish domains. If you run the
example in one domain, only one coordinator is used; no
WS-Coordination protocol messages will be exchanged. This chapter
explains how to run the example in two domains so both protocols,
WS-Coordination and WS-AtomicTransaction (WS-AT), are used, as shown
in WS-Coordination and WS-AtomicTransaction Protocols in Two
GlassFish Domains.
The example also provides the msclient
client,
which is the equivalent of the client servlet shown in Domain
2.
Components in the basicWSTX Example shows the
components that make up the two domain example. Again, the
msclient
client would be equivalent to the client servlet
in Domain 2 in this figure as well.
The service, which runs in domain1, is comprised of two
components:
SimpleService
, a web service that is
implemented as a servlet with transacted operations
SimpleServiceASCMTEJB
, a container-managed
transaction enterprise bean (CMT EJB) web service
The SimpleService
web service uses two Jakarta Messaging
resources that are created in domain1:
jms/ConnectionFactory
, an
XATransaction
connection factory
jms/Queue
, a Jakarta Messaging queue
The LibraryFacadeWebServiceBean
web service uses
the Jakarta Persistence API with two JDBC resources that are
created in domain1:
connectionPool
, an
XATransaction
JDBC connection pool
jdbc/javaProgrammingLibrary
, a JDBC
connection resource
The client servlet, which runs in domain2, initiates the
transaction.