Remember, that both the participating (wsgen_jaxws_wsat_example) and coordinating (wsgen_jaxws_wsat_call_example) service example projects can be found over at GitHub here - https://github.com/ikromin/misc/tree/master/j2ee.
WS-AtomicTransaction Support not Enabled
Lets get started with the very obvious. What happens if you forget to enable WS-AT on your WebLogic Domain? Well, you get errors like this in the WebLogic logs...
Errors
Nov 15, 2018 8:25:10 PM weblogic.wsee.WseeCoreMessages errorLogException
SEVERE: Error while invoking endpoint http://127.0.0.1:7001/wls-wsat/RegistrationPortTypeRPC11 from client; ServiceName: {http://docs.oasis-open.org/ws-tx/wscoor/2006/06}RegistrationService_V11 ; PortName: {http://docs.oasis-open.org/ws-tx/wscoor/2006/06}RegistrationCoordinatorPort ; Client side features: [com.sun.xml.ws.api.addressing.OneWayFeature][javax.xml.ws.soap.AddressingFeature][weblogic.jws.jaxws.client.ClientIdentityFeature]; Client side policies:
<15/11/2018 8:25:10,034 PM AEDT> <Error> <Default> <BEA-000000> <Error while invoking endpoint http://127.0.0.1:7001/wls-wsat/RegistrationPortTypeRPC11 from client; ServiceName: {http://docs.oasis-open.org/ws-tx/wscoor/2006/06}RegistrationService_V11 ; PortName: {http://docs.oasis-open.org/ws-tx/wscoor/2006/06}RegistrationCoordinatorPort ; Client side features: [com.sun.xml.ws.api.addressing.OneWayFeature][javax.xml.ws.soap.AddressingFeature][weblogic.jws.jaxws.client.ClientIdentityFeature]; Client side policies: >
Nov 15, 2018 8:25:10 PM weblogic.wsee.WseeCoreMessages errorLogException
SEVERE: Error while invoking endpoint http://127.0.0.1:7001/WsAtExample-1.0/WsAtExample from client; ServiceName: {http://igorkromin.net/wsat/participant}WsAtExampleService ; PortName: {http://igorkromin.net/wsat/participant}WsAtExamplePort ; Client side features: [weblogic.wsee.wstx.wsat.TransactionalFeature][weblogic.jws.jaxws.client.ClientIdentityFeature]; Client side policies:
<15/11/2018 8:25:10,038 PM AEDT> <Error> <Default> <BEA-000000> <Error while invoking endpoint http://127.0.0.1:7001/WsAtExample-1.0/WsAtExample from client; ServiceName: {http://igorkromin.net/wsat/participant}WsAtExampleService ; PortName: {http://igorkromin.net/wsat/participant}WsAtExamplePort ; Client side features: [weblogic.wsee.wstx.wsat.TransactionalFeature][weblogic.jws.jaxws.client.ClientIdentityFeature]; Client side policies: >
The most interesting part of these messages is that the "http://127.0.0.1:7001/wls-wsat/RegistrationPortTypeRPC11" URL is not reachable, that's because the backend services that handle WS-AT registration and coordination haven't been deployed. To deploy them all you need to do is run some WLST. Offline mode mode is the easiest way to do it i.e. shut down your WebLogic first, run these commands and then start WebLogic. Using the same example I used in the previous two articles, with WebLogic dev server 12.2.1.3 installed in /Applications/devtools/wls_12.2.1.3, I first started WLST and then ran the following commands...
WLST
readDomain('/Applications/devtools/wls_12.2.1.3/user_projects/domains/base_domain')
create('ofs','OptionalFeatureDeployment')
cd('OptionalFeatureDeployment/ofs')
create('WSAT', 'OptionalFeature')
cd('OptionalFeature/WSAT')
set('Enabled',true)
updateDomain()
closeDomain()
exit()
You could also choose to create your domain with the 'WebLogic Advanced Web Services for JAX-WS Extension' which will enable WS-AT support for you. Whichever way you go about enabling this support, after this step both the coordinating and participating services should work.
Calling UserTransaction.begin() in the participating service
If you call UserTransaction.begin() in the participating service, you will get an error like this...
Errors
javax.transaction.NotSupportedException: Another transaction is associated with this thread. Existing transaction Xid=BEA1-00032E59B5763057A4BD(150630428),Status=Active,numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=3,seconds left=21,useSecure=false,activeThread=Thread[[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads],SCInfo[base_domain+AdminServer]=(state=active),properties=({weblogic.transaction.foreignXid=FF1D-62393031653936362D313963632D343439612D396661372D653034623365366433623335, weblogic.transaction.partitionName=DOMAIN, weblogic.wsee.wstx.foreignContext=ForeignRecoveryContext[tid=FF1D-62393031653936362D313963632D343439612D396661372D653034623365366433623335, endPointreference=<?xml version="1.0" encoding="UTF-8"?><ns0:EndpointReference xmlns:ns0="http://www.w3.org/2005/08/addressing"><ns0:Address>http://127.0.0.1:7001/wls-wsat/CoordinatorPortType11</ns0:Address><ns0:ReferenceParameters><wls-wsat:txId xmlns:wls-wsat="http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">BEA1-00022E59B5763057A4BD</wls-wsat:txId><wls-wsat:branchQual xmlns:wls-wsat="http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">0BI_WSATGatewayRMf96bb7be-7caf-423d-b5cd-331281352106</wls-wsat:branchQual><wls-wsat:routing xmlns:wls-wsat="http://weblogic.wsee.wstx.wsat/ws/2008/10/wsat">AdminServer</wls-wsat:routing></ns0:ReferenceParameters></ns0:EndpointReference>, version = WSAT11]}),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=AdminServer+127.0.0.1:7001+base_domain+t3+ CoordinatorNonSecureURL=AdminServer+127.0.0.1:7001+base_domain+t3+ coordinatorSecureURL=null, XAResources={WLStore_base_domain_WseeJaxwsFileStore, WSATGatewayRM_AdminServer_base_domain, WLStore_base_domain_WseeFileStore, eis/oracle/in-memory},NonXAResources={})],CoordinatorURL=AdminServer+127.0.0.1:7001+base_domain+t3+)
at weblogic.transaction.internal.TransactionManagerImpl.internalBegin(TransactionManagerImpl.java:315)
at weblogic.transaction.internal.ServerTransactionManagerImpl.internalBegin(ServerTransactionManagerImpl.java:375)
at weblogic.transaction.internal.ServerTransactionManagerImpl.begin(ServerTransactionManagerImpl.java:339)
at weblogic.transaction.internal.TransactionManagerImpl.internalBegin(TransactionManagerImpl.java:300)
at weblogic.transaction.internal.TransactionManagerImpl.begin(TransactionManagerImpl.java:237)
at net.igorkromin.WsAtExampleImpl.doOp(WsAtExampleImpl.java:49)
Since the participating service is enrolled into the global transaction, there is no need to start another UserTransaction, and WebLogic doesn't support nested transactions like this. The participating service should not try to manage transactions internally - it's all handled outside that service.
Calling UserTransaction.commit() or rollback() in the participating service
Similar to the above error condition, if you call UserTransaction.commit() or UserTransaction.rollback(), you will get an exception. The reason is the same, participating services should not try to manipulate transactions directly.
Errors
javax.transaction.SystemException: Cannot call commit on imported transaction directly. Imported transactions should only be committed via XAResource.commit. BEA1-00052E59B5763057A4BD
at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:259)
at weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:389)
at weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:383)
at net.igorkromin.WsAtExampleImpl.doOp(WsAtExampleImpl.java:56)
javax.transaction.SystemException: Cannot call rollback on imported transaction directly. Imported transactions should only be rolled back via XAResource.rollback. BEA1-00072E59B5763057A4BD
at weblogic.transaction.internal.ServerTransactionImpl.rollback(ServerTransactionImpl.java:418)
at weblogic.transaction.internal.TransactionManagerImpl.rollback(TransactionManagerImpl.java:405)
at weblogic.transaction.internal.TransactionManagerImpl.rollback(TransactionManagerImpl.java:399)
at net.igorkromin.WsAtExampleImpl.doOp(WsAtExampleImpl.java:56)
That's it for now. I plan to look at the performance of WS-AT calls vs non-WS-AT calls in the future, so keep an eye out for that article!
-i