| --- |
| title: Transactions |
| --- |
| |
| <!-- |
| 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 Native Client API runs transactions on the server as if they were local to the client application. |
| Thus, the key to running client transactions lies in making sure the server is properly configured and programmed. |
| For complete information about how transactions are conducted on the <%=vars.product_name%> server, see the |
| [Transactions section of the <%=vars.product_name%> User Guide](geodeman/developing/transactions/chapter_overview.html). |
| |
| ## <a id="client-transaction-apis"></a>Native Client Transaction APIs |
| |
| The API for distributed transactions has the familiar relational database methods, `begin`, |
| `commit`, and `rollback`. There are also APIs available to suspend and resume transactions. |
| |
| The C++ classes for executing transactions are: |
| |
| - `apache.geode.client.CacheTransactionManager` |
| - `apache.geode.client.TransactionId` |
| |
| ## <a id="running-nc-transactions"></a>Running Native Client Transactions |
| |
| The syntax for writing client transactions is the same as with server or peer transactions, but when |
| a client performs a transaction, the transaction is delegated to a server that brokers the |
| transaction. |
| |
| Start each transaction with a `begin` operation, and end the transaction with a `commit` or a `rollback`. |
| |
| To maintain cache consistency, the local client cache is not used during a transaction. |
| When the transaction completes or is suspended, local cache usage is reinstated. |
| |
| If the transaction runs on server regions that are a mix of partitioned and replicated regions, |
| perform the first transaction operation on a partitioned region. This sets the server data host for |
| the entire transaction. If you are using PR single-hop, single-hop will be applied as usual to this |
| first operation. |
| |
| In addition to the failure conditions common to all transactions, client transactions can also fail |
| if the transaction delegate fails. If the delegate performing the transaction fails, the transaction |
| code throws a `TransactionException`. |
| |
| ## <a id="nc-transaction-examples"></a>Client Transaction Examples |
| |
| The native client release contains a transaction example in `../examples/cpp/transaction`. |
| |
| The example performs a sequence of operations, displaying simple log entries as they run. |
| |
| - To run an example, follow the instructions in the `README.md` file in the example directory. |
| - Review the source code in the example directory to see exactly how it operates. |
| |
| - You begin by running a script that sets up the server-side environment by invoking `gfsh` commands to create a region, simply called "exampleRegion." |
| |
| - You run the example client application, which performs the following steps: |
| |
| - Connects to the server |
| - Begins a transaction |
| - Performs some `put` operations |
| - Commits the transaction |
| |
| - For this example, the transaction code has these characteristics: |
| |
| - To introduce the possibility of failure, values are randomized from 0 to 9, and the 0 values are |
| treated as unsuccessful. The transaction is retried until it succeeds. |
| |
| - In case the transaction repeatedly fails, the retry loop uses a counter to set a limit of 5 retries. |
| |
| |
| ### <a id="cpp-example"></a>C++ Example |
| |
| This section contains code snippets showing highlights of the C++ transaction example. They are not intended for cut-and-paste execution. |
| For the complete source, see the example source directory. |
| |
| The C++ example creates a cache, then uses it to create a connection pool. |
| |
| ```cpp |
| auto cache = CacheFactory().set("log-level", "none").create(); |
| auto poolFactory = cache.getPoolManager().createFactory(); |
| |
| poolFactory.addLocator("localhost", 10334); |
| auto pool = poolFactory.create("pool"); |
| auto regionFactory = cache.createRegionFactory(RegionShortcut::PROXY); |
| auto region = regionFactory.setPoolName("pool").create("exampleRegion"); |
| ``` |
| |
| The example application gets a transaction manager from the cache and begins a transaction. |
| |
| ```cpp |
| auto transactionManager = cache.getCacheTransactionManager(); |
| |
| transactionManager->begin(); |
| ``` |
| |
| Within the transaction, the client populates data store with 10 values associated with Key1 - Key10. |
| |
| ```cpp |
| for (auto& key : keys) { |
| auto value = getValueFromExternalSystem(); |
| region->put(key, value); |
| } |
| ``` |
| |
| If all `put` operations succeed, the application commits the transaction. Otherwise, it retries up to 5 times if necessary. |
| |
| ```cpp |
| auto retries = 5; |
| while (retries--) { |
| try { |
| transactionManager->begin(); |
| ... // PUT OPERATIONS ... |
| transactionManager->commit(); |
| std::cout << "Committed transaction - exiting" << std::endl; |
| break; |
| } catch ( ... ) { |
| transactionManager->rollback(); |
| std::cout << "Rolled back transaction - retrying(" << retries << ")" << std::endl; |
| } |
| } |
| ``` |