Database Changes, LUW & Locking
sy-dbcnt gives the number of affected rows.
16.1 Write statements
sy-dbcnt gives the number of affected rows. Never modify SAP standard tables directly — use BAPIs or released APIs.
DATA ls_order TYPE zorders.
ls_order = VALUE #( order_id = '0000000100' customer = '0000001000'
order_date = sy-datum amount = '99.90' currency = 'EUR' status = 'O' ).
INSERT zorders FROM @ls_order. " sy-subrc = 4 if key exists
INSERT zorders FROM TABLE @lt_orders ACCEPTING DUPLICATE KEYS.
UPDATE zorders FROM @ls_order. " full row by key
UPDATE zorders SET status = 'C', amount = amount * @lv_discount_factor
WHERE customer = '0000001000' AND status = 'O'. " set-based update
MODIFY zorders FROM @ls_order. " insert or update (upsert)
MODIFY zorders FROM TABLE @lt_orders.
DELETE FROM zorders WHERE status = 'X'.
DELETE zorders FROM @ls_order. " by key16.2 Logical Units of Work (LUW)
A database LUW is a set of DB changes committed or rolled back together. The DB commits implicitly at the end of every dialog step (screen change, RFC call, WAIT, message of type I/W in some contexts).
An SAP LUW spans multiple dialog steps; changes are bundled and executed at COMMIT WORK in one database LUW using update function modules or subroutines ON COMMIT.
Update modules (SE37 processing type "Update module") run in UPD work processes; failures appear in SM13. In RAP, the framework manages the LUW and you must not call COMMIT WORK in behavior implementations (§34).
CALL FUNCTION 'Z_UPDATE_ORDER' IN UPDATE TASK " registered, runs at COMMIT WORK
EXPORTING is_order = ls_order.
PERFORM post_processing ON COMMIT. " legacy
COMMIT WORK. " asynchronous update (V1) — program continues
COMMIT WORK AND WAIT. " synchronous — waits for update completion
ROLLBACK WORK. " discard registered updates and DB changes16.3 Locking with lock objects (SAP enqueue)
Database locks last only for a DB LUW; SAP logical locks are held in the enqueue server across dialog steps.
Locks are cooperative: they only protect against programs that also request them.
Locks passed with _SCOPE = 2 (default) are released by the update task after COMMIT WORK.
Monitor/delete locks: SM12.
SELECT … FOR UPDATE sets a database lock until the end of the DB LUW.
CALL FUNCTION 'ENQUEUE_EZORDERS'
EXPORTING
mode_zorders = 'E'
mandt = sy-mandt
order_id = ls_order-order_id
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc = 1.
MESSAGE |Order is locked by { sy-msgv1 }| TYPE 'E'.
ENDIF.
" ... read, change, save ...
CALL FUNCTION 'DEQUEUE_EZORDERS'
EXPORTING
mode_zorders = 'E'
mandt = sy-mandt
order_id = ls_order-order_id.16.4 Pattern: safe read-change-save
Lock (ENQUEUE_…), handle foreign_lock.
Re-read current data from the database (after locking!).
Validate and change.
Write via update task or direct DML.
COMMIT WORK (releases scope-2 locks) or explicit DEQUEUE_….