blob: 1d160a73384b3b70aec48af8a4f81a04b4d53ac7 [file] [log] [blame]
<% set_title("JTA Global Transactions with", product_name) %>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
The Java Transaction API, JTA, is a standard Java interface you can use to coordinate
<%=vars.product_name%> transactions and JDBC transactions globally under one umbrella.
You can use JTA global transactions to coordinate <%=vars.product_name%> transactions and JDBC transactions.
JTA provides direct coordination between the <%=vars.product_name%> cache and another transactional
resource, such as a database. The parties involved in a JTA transaction include:
- The Java application, responsible for starting the global transaction
- The JTA transaction manager, responsible for opening, committing, and rolling back transactions
- The transaction resource managers, including the <%=vars.product_name%> transaction manager
and the JDBC resource manager, responsible for managing operations in the <%=vars.product_name%> cache and database, respectively
Using JTA, your application controls all transactions in the same standard way, whether the
transactions act on the <%=vars.product_name%> cache, a JDBC resource, or both together. When a JTA
global transaction is finished, the <%=vars.product_name%> transaction and the database transaction are
both complete.
When using JTA global transactions with <%=vars.product_name%>, you have two options:
- Coordinate with an external JTA transaction manager in a container (such as WebLogic or JBoss)
- Set <%=vars.product_name%> as the “last resource” while using a container (such as WebLogic or JBoss) as the JTA transaction manager
An application creates a global transaction by using `javax.transaction.UserTransaction` bound to
the JNDI context `java:/UserTransaction` to start and terminate transactions. During the
transaction, cache operations are done through <%=vars.product_name%> as usual.
**Note:**
See the Java documentation for more information on topics such as JTA, `javax.transaction`, committing and rolling back global transactions, and the related exceptions.
- **[Coordinating with External JTA Transactions Managers](#concept_cp1_zx1_wk)**
<%=vars.product_name%> can work with the JTA transaction managers of several containers like JBoss, WebLogic, GlassFish, and so on.
- **[Using <%=vars.product_name%> as the "Last Resource" in a Container-Managed JTA Transaction](#concept_csy_vfb_wk)**
The "last resource" feature in certain third party containers such as WebLogic allow the use one non-XAResource (such as <%=vars.product_name%>) in a transaction with multiple XAResources while ensuring consistency.
- **[Behavior of <%=vars.product_name%> Cache Writers and Loaders Under JTA](cache_plugins_with_jta.html)**
When <%=vars.product_name%> participates in a global transactions, you can still have <%=vars.product_name%> cache writers and cache loaders operating in the usual way.
- **[Turning Off JTA Transactions](turning_off_jta.html)**
You can configure regions to not participate in any JTA global transaction.
<a id="concept_cp1_zx1_wk"></a>
# Coordinating with External JTA Transaction Managers
<%=vars.product_name%> can work with the JTA transaction managers of several containers such as JBoss, WebLogic, GlassFish, and so on.
At startup <%=vars.product_name%> looks for a TransactionManager
(`javax.transaction.TransactionManager`) that has been bound to its JNDI context. When
<%=vars.product_name%> finds such an external transaction manager, all <%=vars.product_name%> region
operations (such as get and put) will participate in global transactions hosted by this external JTA
transaction manager.
This figure shows the high-level operation of a JTA global transaction whose resources include a <%=vars.product_name%> cache and a database.
<img src="../../images/transactions_jta_app_server.png" id="concept_cp1_zx1_wk__image_C2935E48415349659FC39BF5C7E75579" class="image" />
An externally coordinated JTA global transaction is run in the following manner:
1. Each region operation looks up for presence of a global transaction. If one is detected, then a <%=vars.product_name%> transaction is started automatically, and we register a `javax.transaction.Synchronization` callback with the external JTA transaction manager.
2. At transaction commit, <%=vars.product_name%> gets a `beforeCommit()` callback from the external JTA transaction manager. <%=vars.product_name%> does all locking and conflict detection at this time. If this fails, an exception is thrown back to JTA transaction manager, which then cancels the transaction.
3. After a successful `beforeCommit()`callback, JTA transaction manager asks other data sources to commit their transaction.
4. <%=vars.product_name%> then gets a `afterCommit()` callback in which changes are applied to the cache and distributed to other members.
You can disable JTA in any region that should not participate in JTA transactions. See [Turning Off JTA Transactions](turning_off_jta.html#concept_nw2_5gs_xk).
## <a id="task_j3g_3mn_1l" class="no-quick-link"></a>How to Run a JTA Transaction Coordinated by an External Transaction Manager
Use the following procedure to run a <%=vars.product_name%> global JTA transaction coordinated by an external JTA transaction manager.
1. **Configure the external data sources in the external container.** Do not configure the data sources in cache.xml . They are not guaranteed to get bound to the JNDI tree.
2.
Configure <%=vars.product_name%> for any necessary transactional behavior in the `cache.xml` file. For example, enable `copy-on-read` and specify a transaction listener, as needed. See [Safe Entry Modification](../../basic_config/data_entries_custom_classes/managing_data_entries.html#managing_data_entries__section_A0E0F889AC344EFA8DF304FD64418809).
3.
Make sure that JTA transactions are enabled for the regions that will participate in the transaction. See [Turning Off JTA Transactions](turning_off_jta.html#concept_nw2_5gs_xk) for details.
4.
Start the transaction through the external container.
5.
Initialize the <%=vars.product_name%> cache. <%=vars.product_name%> will automatically join the transaction.
6.
Execute operations in the cache and the database as usual.
7.
Commit the transaction through the external container.
<a id="concept_csy_vfb_wk"></a>
# Using <%=vars.product_name%> as the "Last Resource" in a Container-Managed JTA Transaction
The "last resource" feature in certain third party containers such as WebLogic allow the use of one
non-XAResource (such as <%=vars.product_name%>) in a transaction with multiple XAResources while
ensuring consistency.
In the previous two JTA transaction use cases, if the <%=vars.product_name%> member fails after the
other data sources commit but before <%=vars.product_name%> receives the `afterCommit` callback,
<%=vars.product_name%> and the other data sources may become inconsistent. To prevent this from
occurring, you can use the container's "last resource optimization" feature, with
<%=vars.product_name%> set as the "last resource". Using <%=vars.product_name%> as the last resource
ensures that in the event of failure, <%=vars.product_name%> remains consistent with the other
XAResources involved in the transaction.
To accomplish this, the application server container must use a JCA Resource Adapter to accomodate
<%=vars.product_name%> as the transaction's last resource. The transaction manager of the container
first issues a "prepare" message to the participating XAResources. If the XAResources all accept the
transaction, then the manager issues a "commit" instruction to the non-XAResource (in this case,
<%=vars.product_name%>). The non-XAResource (in this case, <%=vars.product_name%>) participates as a
local transaction resource. If the non-XAResource fails, then the transaction manager can rollback
the XAResources.
<img src="../../images/transactions_jca_adapter.png" id="concept_csy_vfb_wk__image_opb_sgb_wk" class="image" />
<a id="task_sln_x3b_wk"></a>
## How to Run JTA Transactions with <%=vars.product_name%> as a "Last Resource"
1. Locate the version-specific `geode-jca` RAR file within
the `lib` directory of your <%=vars.product_name%> installation.
2. Add your container-specific XML file to the `geode-jca` RAR file.
<ol>
<li>Create a container-specific resource adapter XML file named &lt;container&gt;-ra.xml. For example, an XML file for a WebLogic resource adapter XML file might look something like this:
``` pre
<?xml version="1.0"?>
<!DOCTYPE weblogic-connection-factory-dd PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 9.0.0 Connector//EN'
'http://www.bea.com/servers/wls810/dtd/weblogic810-ra.dtd'>
<weblogic-connection-factory-dd>
<connection-factory-name>GFE JCA</connection-factory-name>
<jndi-name>gfe/jca</jndi-name>
</weblogic-connection-factory-dd>
```
</li>
<li>Create a folder named `META-INF`, and place the container-specific XML file inside the directory. For example, the folder structure would look like this:
``` pre
META-INF/weblogic-ra.xml
```
</li>
<li>Navigate to the directory above the `META-INF` folder and execute the following command, with appropriate substitutions for
path and file names:
``` pre
$ jar -uf /path/to/lib/geode-jca-X-X-X.rar META-INF/weblogic-ra.xml
```
</li>
</ol>
3. Make sure that the `geode-dependencies.jar` is accessible in the CLASSPATH of the JTA transaction coordinator container.
4. Deploy the version-specific `geode-jca` RAR file on the JTA transaction coordinator container. When deploying the file, you specify the JNDI name and so on.
5. Configure <%=vars.product_name%> for any necessary transactional behavior. Enable `copy-on-read` and specify a transaction listener, if you need one. See [Safe Entry Modification](../../basic_config/data_entries_custom_classes/managing_data_entries.html#managing_data_entries__section_A0E0F889AC344EFA8DF304FD64418809).
6. Get an initial context through `org.apache.geode.cache.GemFireCache.getJNDIContext`. For example:
``` pre
Context ctx = cache.getJNDIContext();
```
This returns `javax.naming.Context` and gives you the JNDI associated with the cache. The context contains the `TransactionManager`, `UserTransaction`, and any configured JDBC resource manager.
7. Start and commit the global transaction using the `UserTransaction` object rather than with <%=vars.product_name%>'s `CacheTransactionManager`.
``` pre
UserTransaction txManager = (UserTransaction)ctx.lookup("java:/UserTransaction");
```
8. Obtain a <%=vars.product_name%> connection.
``` pre
GFConnectionFactory cf = (GFConnectionFactory) ctx.lookup("gfe/jca");
//This step of obtaining connection is what begins the
//LocalTransaction.
//If this is absent, GFE operations will not be part of any
//transaction
GFConnection gemfireConn = (GFConnection)cf.getConnection();
```