SCA transaction intents
Service Component Architecture (SCA) provides declarative mechanisms in the form of intents for describing the transactional environment required by components.
This topic covers:
- Use a global transaction
- Use local transaction containment
- Transaction intent default behavior
- Mapping of SCA intents on services to EJB or Spring transaction attributes
- Obtaining the transaction manager in Spring applications
- (iseries) Managed local or global transactions with JDBC data sources and IBM i
Use a global transaction
Components that use a synchronous interaction style can be part of a single, distributed ACID transaction within which all transaction resources are coordinated to either atomically commit or roll back. This is specified using the managedTransaction.global intent in the requires attribute of the <implementation.java> element as shown later in this section.
<component name="DataAccessComponent"> <implementation.java class="example.DataAccessImpl" requires="managedTransaction.global"/> </component>For implementation.spring components, specify the transaction attribute in the Spring application context file. For implementation.jee components, specify the transaction attribute in the EJB deployment descriptor.
It is possible to control whether a component's service runs under its client's global transaction by specifying either the propagatesTransaction or suspendsTransaction intent on the component's <service> element.
- propagatesTransaction
- The service runs under its client's global transaction. If the client is not running in a global transaction or chose not to propagate its global transaction, the service runs in its own global transaction.
- suspendsTransaction
- The service runs in its own global transaction separate from the client transaction.
Specify the propagatesTransaction or suspendsTransaction intent on the component's <service> element only for services in implementation.java components. For implementation.spring components, specify the transaction attribute in the Spring application context file. For implementation.jee components, specify the transaction attribute in the EJB deployment descriptor.
It is also possible to control whether a component global transaction is propagated to a referenced service by specifying either the propagatesTransaction or suspendsTransaction intent on the component <reference> element.
- propagatesTransaction
- The component's global transaction is made available to the referenced service. The referenced service might or may not use this transaction depending on how it is configured.
- suspendsTransaction
- The component's global transaction is not made available to the referenced service.
We can specify the propagatesTransaction or suspendsTransaction intent on the component's <reference> element for references in all implementation types.
Transaction context is never propagated on @OneWay methods. The SCA run time ignores propagatesTransaction for OneWay methods.
Further, the product does not support propagatesTransaction intent on the binding.atom or binding.jsonrpc elements.
The following example shows the use of the managedTransaction.global, propagatesTransaction, and suspendsTransaction intents. The DataUpdateComponent runs in its own global transaction, not in its client's transaction, because suspendsTransaction is specified on its <service> element. Its global transaction is propagated to the referenced service DataAccessComponent because propagatesTransaction is specified on its <reference> element.
<component name="DataUpdateComponent"> <implementation.java class="example.DataUpdateImpl" requires="managedTransaction.global"/> <service name="DataUpdateService" requires="suspendsTransaction"/> <reference name="myDataAccess" target="DataAccessComponent" requires="propagatesTransaction"/> </component>Propagating transactions over the web service binding requires the use of a WebSphere policy set containing the WS-Transaction policy type. We can set up this policy set in one of the following ways:
- We can import the WSTransaction policy set provided with the product.
- We can create our own policy set and include the WS-Transaction policy type.
The following example assumes the use of the WSTransaction policy set.
<composite name="WSDataUpdateComposite" xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:ws="http://www.ibm.com/xmlns/prod/websphere/sca/1.0/2007/06"> <component name="WSDataUpdateComponent"> <implementation.java class="example.DataUpdateImpl" requires="managedTransaction.global"/> <service name="DataUpdateService" requires="propagatesTransaction"> <binding.ws ws:wsPolicySet="WSTransaction"/> </service> <reference name="myDataBuddy" target="DataBuddyComponent" requires="propagatesTransaction"> <binding.ws ws:wsPolicySet="WSTransaction"/> </reference> </component> </composite>Transaction propagating might not result in a managed connection. Use a qualifying Java EE module for a managed connection and connection sharing.
Use local transaction containment
Business logic might have to access transactional resource managers without the presence of a global transaction. A component can be configured to run under local transaction containment (LTC). The SCA runtime starts an LTC before dispatching a method on the component and completes the LTC at the end of the method dispatch. The component's interactions with resource providers (such as databases) are managed within resource manager local transactions (RMLTs). A resource manager local transaction (RMLT) represents a unit of recovery on a single connection that is managed by the resource manager.
The local transaction containment policy is configured by using an intent. There are two choices:
- managedTransaction.local
- Use this intent when each interaction with a resource manager should be part of an extended local transaction that is committed at the end of the method. The SCA runtime wraps interactions with each resource manager in a resource manager local transaction (RMLT). The SCA runtime commits each RMLT at the end of method dispatch, unless an unchecked exception occurs, in which case the SCA runtime stops each RMLT. The component might not use resource manager commit/rollback interfaces or set AutoCommit to true. If multiple resource managers are used, the RMLTs are committed independently so it is possible for some to fail and some to succeed. If this behavior is not what we want, use a global transaction.
- noManagedTransaction
- The SCA runtime does not wrap interactions with resource managers in a RMLT. The component implementation manages the start and end of its own RMLTs or gets AutoCommit behavior (which commits following each use of a resource) by default. The component must complete any RMLTs prior to the end of the method dispatch otherwise the SCA runtime stops them.
The intent is specified using the requires attribute on the <implementation.java> element. The following is an example:
<component name="DataAccessLocalComponent"> <implementation.java class="example.DataAccessImpl" requires="managedTransaction.local"/> </component>A local transaction cannot be propagated from one component to another. It is an error to specify propagatesTransaction on a component's <service> if the component uses the managedTransaction.local or noManagedTransaction intent.
The SCA run time performs a rollback under the following circumstances:
- When managedTransaction.global is used, the SCA run time performs a rollback if the component method that started the global transaction throws an unchecked exception. An unchecked exception is a subclass of java.lang.RuntimeException or java.lang.Error. A checked exception does not force a rollback.
- When managedTransaction.local is used, the SCA run time performs a rollback if the component method throws an unchecked exception. An unchecked exception is a subclass of java.lang.RuntimeException or java.lang.Error. A checked exception does not force a rollback.
- When noManagedTransaction is used, the SCA run time performs a rollback of any RMLT that has not been committed by the component method, regardless of whether the method throws an exception or not.
When managedTransaction.global or managedTransaction.local is used, the business logic can force a rollback using the UOWSynchronization interface.
com.ibm.websphere.uow.UOWSynchronizationRegistry uowSyncRegistry = com.ibm.wsspi.uow.UOWManagerFactory.getUOWManager(); uowSyncRegistry.setRollbackOnly();
Transaction intent default behavior
If transactional intents are not specified, the default behavior is vendor-specific. If a transactional intent in not specified for the implementation, the default is managedTransaction.global. If a transactional intent is not specified for a service or reference, the default is suspendsTransaction. IBM recommends to specify the required intents rather than to rely on default behavior so that the application is portable.
Use @Requires annotation to specify transaction intents
We can also specify transaction intents in the implementation class using the @Requires annotation. The general form of the annotation is:
@Requires("{http://www.osoa.org/xmlns/sca/1.0}intent")
For example, we can use the following in the implementation class:
@Requires("{http://www.osoa.org/xmlns/sca/1.0}managedTransaction.global")
We can specify required intents on various elements, including the composite, component, implementation, service and reference elements. An element inherits the required intents of its parent element except when they conflict. For example, if a composite element requires managedTranaction.global and a component element requires managedTransaction.local, then the component uses managedTransaction.local.
We cannot use the @Requires annotation for implementation.spring components.
Mapping of SCA intents on services to EJB or Spring transaction attributes
The following table contains information from Section 5.3 of the SCA Java EE Integration specification and lists the mapping of SCA intents on services to EJB or Spring transaction attributes.
policies. See Section 5.3 of the SCA Java EE Integration
EJB transaction attribute SCA Transaction Policy required intents on services SCA Transaction Policy required intents on implementations NOT_SUPPORTED suspendsTransaction
REQUIRED propagatesTransaction managedTransaction.global SUPPORTS propagatesTransaction managedTransaction.global REQUIRES_NEW suspendsTransaction managedTransaction.global MANDATORY propagatesTransaction managedTransaction.global NEVER suspendsTransaction
For MANDATORY and NEVER attributes, policy mapping might not be accurate. These attributes express responsibilities of the EJB container as well as the EJB implementer rather then express a requirement on the service consumer.
Obtaining the transaction manager in Spring applications
The product does not support local JNDI lookups in Spring applications referenced from SCA components. Thus, we cannot use <tx:jta-transaction-manager/> in the Spring application context file to obtain the WebSphere transaction manager.
To obtain the WebSphere transaction manager, add the following definition explicitly to the Spring application-context.xml file:
<bean id="WASTranMgr" class="com.ibm.wsspi.uow.UOWManagerFactory" factory-method="getUOWManager"/> <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"> <property name="uowManager" ref="WASTranMgr"/> <property name="autodetectUserTransaction" value="false"/> </bean>
(iseries) Managed local or global transactions with JDBC data sources and IBM i
If we use managed local transaction intent or global transaction intent in SCA composites, this will turn off autocommit when you use JDBC on the IBM i platform. If multiple SQL jobs need to lock the same table for an update, the following exception will appear:
SQLException: com.ibm.db2.jdbc.app.DB2DBException: Row or object WAREHOUSE in CBIVP type *FILE in use
The first SQL job that locks the table never commits the transaction, and the lock is never released. Global and local transactions for SCA are not supported when you use JDBC to connect to resources, so use noManagedTransaction intents. Change the following in the SCA composite files to switch to the noManagedTransaction intent:
- Change
requires="managedTransaction.local"
and
requires="managedTransaction.global"
to
requires="noManagedTransaction"
- Change
requires="propagatesTransaction"
to
requires="suspendsTransaction"
Related concepts
Transaction support in WebSphere Application Server
Related tasks
Configure transactions for the SCA JMS binding
Related information:
SCA specifications