---
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 .NET classes for executing transactions are:

-   `Apache.Geode.Client.CacheTransactionManager`
-   `Apache.Geode.Client.TransactionId`

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 transaction examples written for .NET and C++. The examples are
located in `../examples/dotnet/transaction` and `../examples/cpp/transaction`, respectively. 

Both examples perform the same 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 servers-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="dotnet-example"></a>.NET Example

This section contains code snippets showing highlights of the .NET transaction example. They are not intended for cut-and-paste execution.
For the complete source, see the example source directory.

The .NET example creates a cache, then uses it to create a connection pool.

```csharp
   var cache = new CacheFactory()
       .Set("log-level", "none").Create();

   var poolFactory = cache.GetPoolFactory()
       .AddLocator("localhost", 10334);
      
   poolFactory.Create("pool");

   var regionFactory = cache.CreateRegionFactory(RegionShortcut.PROXY)
       .SetPoolName("pool");
   var region = regionFactory.Create<string, int>("exampleRegion");
```

The example application gets a transaction manager from the cache and begins a transaction.

```csharp
       cache.CacheTransactionManager.Begin();
```

Within the transaction, the client populates data store with 10 values associated with Key1 - Key10.

```csharp
       foreach(var key in keys)
       {
         var 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.

```csharp
   var retries = 5;
   while(retries-- > 0)
   {
     try 
     {
       ... // PUT OPERATIONS ...
       cache.CacheTransactionManager.Commit();
       Console.WriteLine("Committed transaction - exiting");
       break;
     } catch
     {
       cache.CacheTransactionManager.Rollback();
       Console.WriteLine("Rolled back transaction - retrying({0})", 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;
    }
  }
```
