---
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`

## <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/dotnet/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="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);
     }
   }
```

