# How to Use BAPI_TRANSACTION_COMMIT Correctly

> Source: https://netray.co/erp-help/sap-bapi-transaction-commit-how-to
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

SAP's BAPI programming model separates business logic from the database commit on purpose, so a caller must explicitly call BAPI_TRANSACTION_COMMIT after a successful BAPI - usually with WAIT = 'X' - or the created object never actually persists. Skipping this step, or forgetting WAIT, is the most common reason a BAPI 'runs fine' but nothing gets saved.

## Kind

how-to

## System

sap

## Erp

SAP ERP (ECC 6.0 / S/4HANA)

## Module

ABAP Development / RFC-BAPI

## Query

how to use BAPI_TRANSACTION_COMMIT correctly

## Alternate Queries

- BAPI_TRANSACTION_COMMIT vs COMMIT WORK
- when to call BAPI_TRANSACTION_COMMIT
- BAPI created but not saved SAP

## Applies To

SAP ECC 6.0 and S/4HANA, classic BAPI framework (RFC-enabled function modules)

## Steps

### Call the commit pattern correctly

**Items:**

- Call the business BAPI (for example BAPI_SALESORDER_CREATEFROMDAT2) and capture its RETURN or BAPIRET2 table.
- Check RETURN for any entries with TYPE = 'E' (error) or 'A' (abort) before doing anything else - do not assume success just because the call itself did not throw a system exception.
- If no error or abort entries exist, call BAPI_TRANSACTION_COMMIT to finalize the update in the current LUW.
- Pass WAIT = 'X' on the commit whenever your program (or an external caller) needs the created object number to be usable immediately afterward, since the commit can otherwise return before the update task actually finishes.
- If RETURN does contain an error, call BAPI_TRANSACTION_ROLLBACK instead of committing, to cleanly undo the logical unit of work.
- When calling from an external system over RFC, issue the commit as an explicit follow-up call within the same connection/session context - do not assume the calling framework commits for you.
- Do not embed COMMIT WORK inside a custom BAPI wrapper itself; leave the commit decision to the caller so multiple BAPIs can be chained into one logical unit of work and committed together.
- After a WAIT commit, re-select the created object fresh (rather than trusting a number returned pre-commit) to confirm the save actually happened.

## Sections

### Why BAPIs do not auto-commit

**Body:**

SAP's BAPI programming model deliberately separates business logic from the commit decision. This lets a caller chain several BAPIs together - for example, create a sales order and then immediately change a partner on it - as one logical unit of work, and commit once at the end rather than after every individual call.

That design means every BAPI call that changes data leaves the actual database commit to the caller. If nothing ever calls BAPI_TRANSACTION_COMMIT, the change stays in the current LUW and is effectively lost when the session ends or a later COMMIT WORK/rollback happens elsewhere in the program.

### WAIT = 'X' and why it matters

**Body:**

BAPI_TRANSACTION_COMMIT without WAIT can return control to your program before the associated update task (V1/V2) has actually finished writing to the database. If your program immediately re-reads the object it just created, this race can produce a 'not found' or stale result even though the commit ultimately succeeds moments later.

Passing WAIT = 'X' tells the kernel to hold the commit call until the update task completes, which is the safe choice whenever the very next statement depends on the just-created data being visible.

**Code:**

- CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2'
-   EXPORTING order_header_in = ls_header
-   IMPORTING salesdocument   = lv_vbeln
-   TABLES    return          = lt_return.
- 
- READ TABLE lt_return WITH KEY type = 'E' TRANSPORTING NO FIELDS.
- IF sy-subrc = 0.
-   CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
- ELSE.
-   CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'.
- ENDIF.

### Error handling and rollback

**Body:**

The standard pattern is to treat any RETURN entry with TYPE 'E' or 'A' as a failure that requires BAPI_TRANSACTION_ROLLBACK, while TYPE 'S' (success) and 'I' (information) generally mean it is safe to proceed to commit. TYPE 'W' (warning) needs judgment - some warnings are informational, others indicate a partial or unexpected result worth stopping for.

Do not silently ignore the RETURN table and commit unconditionally after any BAPI call; that is the second most common cause (after a missing commit entirely) of BAPIs appearing to fail intermittently in production.

### RFC and background job considerations

**Body:**

When a BAPI is called from an external system over RFC (an integration, middleware, or a custom client), the commit still needs to happen within the same RFC connection/LUW context as the original BAPI call - it is not automatic just because the framework made the call for you.

In a background job (SM36), the same commit pattern applies within that job's LUW. A job that calls a BAPI and never commits will complete 'successfully' from a job-log perspective while saving nothing, which is a confusing failure mode to debug after the fact.

## Pitfalls

- Forgetting BAPI_TRANSACTION_COMMIT entirely - the BAPI returns a document number that never actually persists to the database.
- Omitting WAIT = 'X' and then immediately reading the just-created object in the same session, hitting a record-not-found race against the update task.
- Calling COMMIT WORK directly instead of BAPI_TRANSACTION_COMMIT in mixed custom/standard BAPI chains, which can bypass BAPI-specific finalization logic some objects rely on.
- Treating any non-error RETURN entry as full success without checking for TYPE 'W' entries that may indicate a partial or unexpected result.
- Committing before fully checking RETURN, then discovering an error only after the LUW has already persisted a partial or incorrect document.
- Embedding a commit inside a reusable custom BAPI wrapper, which prevents callers from chaining it with other BAPIs into a single logical unit of work.

## Ai Angle

SyteRay-style grounded code assistance on a custom RFC/BAPI wrapper can flag a missing BAPI_TRANSACTION_COMMIT, a missing WAIT, or an unchecked RETURN table directly in the ABAP source as it is written or reviewed, catching the exact class of bug that otherwise only surfaces later as 'the interface ran but nothing saved.'

## Faq

### Do I need to call BAPI_TRANSACTION_COMMIT after every single BAPI?

**Answer:** Not after every call if you are deliberately chaining several BAPIs into one logical unit of work - commit once after the last one succeeds. But every chain must end with exactly one commit (or rollback) or nothing gets saved.

### Is BAPI_TRANSACTION_COMMIT the same as COMMIT WORK?

**Answer:** They are closely related - BAPI_TRANSACTION_COMMIT internally triggers a COMMIT WORK - but calling the BAPI wrapper is the documented, supported pattern for BAPI-created objects and is what standard SAP documentation and most BAPIs expect callers to use.

### Why did my BAPI return a document number but the document does not exist when I query it later?

**Answer:** The most common cause is a missing or misplaced BAPI_TRANSACTION_COMMIT call, or a commit without WAIT followed by an immediate read before the update task finished. Confirm the commit actually ran and consider adding WAIT = 'X'.

### Should I use WAIT = 'X' on every commit?

**Answer:** Use it whenever the next step depends on the created object being immediately visible, such as reading it back or passing its number to another synchronous call. For pure fire-and-forget postings it is not strictly required, but it removes a class of timing bugs at a small performance cost.

## Search terms

BAPI_TRANSACTION_COMMIT, BAPI_TRANSACTION_ROLLBACK, SAP BAPI commit WAIT, BAPI created but not saved, SAP BAPIRET2, SAP ABAP BAPI programming, BAPI_TRANSACTION_COMMIT vs COMMIT WORK, SAP RFC commit pattern, SAP BAPI update task, SAP BAPI best practices

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
