# Transactions

xTransaction in WHO with passing down to all BusObjects (BusinessObjects). The WHO should have the responsability for commit/rollback. Each BusinessObject should issue an exception in case of an error and this exception should be caught by the WHO. This will allow multi-level BusinessObjects working together without suppressing the real exception on an intermediary level (by a “parent” BusinessObject).

Each WHO has a property called “TransactionCreate” (preset on TRUE) which:

* creates a transaction-object (called “Transaction”) when a module is opened and applies it to its BusinessObject
*

```
the Save method from the base class automatically commits the transaction
```

*

```
when the module is closed that transaction calls the dispose method
```

“TransactionCreate” will be set on FALSE (in the constructor) if the module:

* does not work with the database
*

```
is an internal module (xModule)
```

*

```
is response module and receives the transaction from the parent context
```

*

```
does not require transactions for any other reason
```

{% hint style="warning" %}
Notice that one response Module could have TransactionCreate set on true, because while opening a module using OpenResponseModule with Transaction as parameter, it will automatically set TransactionCreate on false and will pass the Transaction of the parent.
{% endhint %}

Each action done in the WHO needs to commit its changes. The ***handling*** of the exception is done in the ***WHO***.

{% hint style="success" %}
Best practice: The BusinessObjects should **not** return negative values for errors. Instead, exceptions, containing all the details about the error, should be thrown.
{% endhint %}

Example: Steps to implement for proper transaction management:

In the constructor of the WHO specify that a transaction is needed. This is all that has to be done. This transaction is passed on to the BusObj, which then gives it to its children, and so on…

```csharp
public wndPers() : base("busPers")
{
    TransactionCreate = true;
}
```

The Method inside the WHO should look like this:

```csharp
public virtual void GeneratePers(dsBPartnerCustom.PersRow row)
{
    //     ......
    // GP generieren
    try
    {
        int retVal = BusObj.GenerateBPContact(lrTree.LRTree, row, true);
        Transaction.Commit();
    }
    catch (Exception ex)
    {
        Transaction.Rollback();
        xMessageBox.ShowException(ex, "Fehler beim Erstellen des Geschäftspartners.");     
    }
}
```

{% hint style="info" %}
retVal is used to know the result of the action (if all went well), but not for Errors. All errors happening inside GenerateBP pop out as exceptions. Also important here is that first the transaction is rolled back, THEN the message is shown. This way, the user can “study” the message without eventually locking some Database-Rows.
{% endhint %}

```csharp
public virtual void GenerateBPContact (LrTree tree, dsBPartnerCustom.PersTelRow row, bool genSubPers = true)
{
		// Inits		
		// ...
		// UnterBP
		
		if (genSubPers)
		{
				foreach (var child in children)
				{
						GenerateBP (tree, child.Info.DataRow, true);
						int unterBP = child.Info.DataRow["nr"].ToInt(0);
				}
		}

    //...
    
    return 1;
}
```

{% hint style="info" %}
Notice that GenerateBP(...) is a recursive function and only if ALL BP are created correctly, the WHO-Method will Commit the transaction. If an error occurs, everything is rolled back.
{% endhint %}

To create a busObj inside a busObj, use the Function „CreateChildBusinessObject”. This way, the transaction is passed on to this new Object.&#x20;

Example:

```csharp
var pers = this.CreateChildBusinessObject<busPers>();
```

Using current object transaction to do other sql operations

```csharp
try
{
    Sql.Execute(Transaction, "DELETE FROM gebinde WHERE bel_typ = {0} AND bel_nr = {1} AND typ = 10", belTyp, belNr);
}
catch (Exception)
{
    if (Transaction != null)
    {
        Rollback();
    }

    throw;
}

int result = Save();
if (result < 0 && Transaction != null)
{
    Rollback();
}
```

{% hint style="warning" %}
Note:  CurrentTransaction is obsolete, Transaction is the new name of the transaction property
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tldocs.gitbook.io/documentation/framework/window-handling-object/transactions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
