You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Business logic often needs to prevent two users from editing the same object at the same time. Because abap2UI5 runs stateless by default, locks held with `ENQUEUE` / `DEQUEUE` are released at the end of each roundtrip — so locking needs a deliberate approach.
6
+
In classic SAP GUI, a transaction like `VA02` calls `ENQUEUE_EVVBAK` and the lock lives as long as the dialog session. Web apps are different: each roundtrip is a fresh ABAP session by default, so a lock set in one roundtrip is gone by the next. Locking in abap2UI5 means picking a deliberate strategy for two questions:
7
+
8
+
| Phase | Question |
9
+
|---|---|
10
+
|**Edit**| What happens while the user is thinking and typing? |
11
+
|**Save**| What happens the moment they hit save? |
12
+
13
+
The patterns below combine in different ways. The examples use the sales order header table `VBAK` and its standard enqueue object `EVVBAK`, but the same shapes apply to any table. All snippets have a complete, copy-paste-ready demo class — sample numbers are linked next to each section.
14
+
15
+
#### No Locking
16
+
The minimal starting point — the user edits and saves, no lock and no conflict check. Last save wins, silently. Fine for personal sandboxes and throwaway demos, but rarely what you want in production. See sample `Z2UI5_CL_DEMO_APP_S_07`.
7
17
8
18
#### Lock at Save
9
-
The simplest pattern: do not hold a lock while the user thinks. Acquire it the moment the user saves, write, commit, and release — all in one short roundtrip. Combine with an optimistic check (e.g. a last-changed timestamp) to catch conflicts from outside your app.
19
+
Do not hold a lock while the user thinks. Acquire it the moment they save, write, commit, and release — all in one short roundtrip:
20
+
```abap
21
+
METHOD on_event_save.
22
+
23
+
CALL FUNCTION `ENQUEUE_EVVBAK`
24
+
EXPORTING
25
+
mode_vbak = `E`
26
+
mandt = sy-mandt
27
+
vbeln = vbeln
28
+
EXCEPTIONS
29
+
foreign_lock = 1
30
+
system_failure = 2
31
+
OTHERS = 3.
32
+
33
+
IF sy-subrc <> 0.
34
+
client->message_box_display( `Locked by another user.` ).
35
+
RETURN.
36
+
ENDIF.
37
+
38
+
UPDATE vbak SET auart = @auart WHERE vbeln = @vbeln.
39
+
COMMIT WORK.
40
+
41
+
CALL FUNCTION `DEQUEUE_EVVBAK`
42
+
EXPORTING
43
+
mode_vbak = `E`
44
+
mandt = sy-mandt
45
+
vbeln = vbeln.
46
+
47
+
ENDMETHOD.
48
+
```
10
49
11
-
#### Lock with a Stateful Session
12
-
For classic SAP GUI-like behaviour, switch the session to stateful and call the lock function module. The lock survives subsequent roundtrips as long as the session stays alive:
50
+
The lock exists for milliseconds, so this scales — but two parallel saves can still race if the timestamps line up, and the second one silently overwrites the first. See sample `Z2UI5_CL_DEMO_APP_S_08`.
51
+
52
+
#### Optimistic Check
53
+
On read, remember the record's change timestamp. On save, re-read and reject if it shifted in the meantime — the same idea as an HTTP ETag:
13
54
```abap
14
-
CLASS z2ui5_cl_sample_lock DEFINITION PUBLIC.
55
+
METHOD data_read.
56
+
SELECT SINGLE aedat, UPD_TMSTMP FROM vbak
57
+
INTO ( @token_aedat, @token_aezet )
58
+
WHERE vbeln = @vbeln.
59
+
ENDMETHOD.
60
+
61
+
METHOD on_event_save.
15
62
16
-
PUBLIC SECTION.
17
-
INTERFACES z2ui5_if_app.
18
-
DATA varkey TYPE char120.
63
+
SELECT SINGLE aedat, UPD_TMSTMP FROM vbak
64
+
INTO ( @DATA(now_aedat), @DATA(now_aezet) )
65
+
WHERE vbeln = @vbeln.
19
66
20
-
ENDCLASS.
67
+
IF now_aedat <> token_aedat OR now_aezet <> token_aezet.
No lock is held during the edit phase, so this scales to many concurrent users and catches conflicts even from outside your app (SE16, batch jobs, RFC). See sample `Z2UI5_CL_DEMO_APP_S_09`.
35
78
36
-
IF sy-subrc = 0.
37
-
client->set_session_stateful( ).
38
-
ELSE.
39
-
client->set_session_stateful( abap_false ).
40
-
client->nav_app_leave( ).
41
-
ENDIF.
79
+
Pick a column that *always* updates on writes. If anyone writes the table bypassing `AEDAT` / `UPD_TMSTMP`, the check silently misses real conflicts.
42
80
43
-
ENDIF.
81
+
#### Combined (recommended default)
82
+
**Lock at Save** plus the **Optimistic Check** is the safest stateless pattern and the sensible production default — the enqueue serializes parallel saves of *this* app, the timestamp check catches everyone else. See sample `Z2UI5_CL_DEMO_APP_S_10`.
44
83
45
-
"release the lock on exit
46
-
IF client->check_on_event( `BACK` ).
47
-
client->set_session_stateful( abap_false ).
48
-
client->nav_app_leave( ).
49
-
ENDIF.
84
+
#### Stateful Session
85
+
For classic SAP GUI-like behaviour, switch the session to stateful and call the lock function module on init. The lock survives subsequent roundtrips as long as the session stays alive:
86
+
```abap
87
+
IF client->check_on_init( ).
88
+
89
+
CALL FUNCTION `ENQUEUE_EVVBAK`
90
+
EXPORTING
91
+
mode_vbak = `E`
92
+
mandt = sy-mandt
93
+
vbeln = vbeln
94
+
EXCEPTIONS
95
+
foreign_lock = 1
96
+
system_failure = 2
97
+
OTHERS = 3.
98
+
99
+
IF sy-subrc = 0.
100
+
client->set_session_stateful( ).
101
+
ELSE.
102
+
client->message_box_display( `Locked by another user.` ).
103
+
client->nav_app_leave( ).
104
+
RETURN.
105
+
ENDIF.
106
+
107
+
ENDIF.
108
+
```
50
109
51
-
ENDMETHOD.
52
-
ENDCLASS.
110
+
While the app is open, an entry for `EVVBAK` / `0000004711` is visible in SM12. The user can navigate, type, wait — the lock stays. On exit, release it explicitly:
111
+
```abap
112
+
CALL FUNCTION `DEQUEUE_EVVBAK`
113
+
EXPORTING
114
+
mode_vbak = `E`
115
+
mandt = sy-mandt
116
+
vbeln = vbeln.
117
+
client->set_session_stateful( abap_false ).
53
118
```
54
119
55
-
See sample `Z2UI5_CL_DEMO_APP_350` for a complete example.
120
+
See samples `Z2UI5_CL_DEMO_APP_S_11` and `Z2UI5_CL_DEMO_APP_350` for complete examples.
56
121
57
122
::: warning
58
-
A stateful session pins a work process per active user. Use it only for low-traffic, internal apps. For background and the wider lock discussion, see [Statefulness, Locks](../../advanced/stateful.md).
123
+
Each active user pins a work process. Use stateful sessions only for low-traffic, internal apps. Always pair `set_session_stateful( )` with an explicit `set_session_stateful( abap_false )` on every exit path — otherwise a leaked enqueue blocks future users until the session times out.
59
124
:::
60
125
126
+
#### Soft Lock
127
+
A soft lock is a row in a custom Z table marking *"user X is editing object Y"*. It is **not** enforced by the SAP kernel — only your app code respects it — so use it for UX feedback ("locked by Alice since 09:32") and always layer it on top of a real save-time guard. A minimal schema:
| LOCKED_AT | TIMESTAMPL | When the lock started |
135
+
136
+
A user closing the browser without pressing *Release* leaves the row behind, so add a cleanup job that deletes entries older than, say, 30 minutes. See sample `Z2UI5_CL_DEMO_APP_S_12` (with the matching `Z2UI5_SAMPLE_01` table).
137
+
61
138
#### RAP Drafts
62
-
On modern releases, RAP draft-enabled business objects manage locking for you: a draft holds an exclusive lock for its owner while the user keeps editing — no stateful session, no `ENQUEUE_*` call. If a released SAP BO already covers your object, this is usually the simplest path. See [Draft Handling](./draft.md).
139
+
On modern releases, RAP draft-enabled business objects manage locking for you: the draft holds an exclusive lock for its owner while the user keeps editing — no stateful session, no `ENQUEUE_*` call. If a released SAP BO already covers your object, this is usually the simplest path. See [Draft Handling](./draft.md).
63
140
64
141
#### Lock-Manager Add-on
65
142
The community add-on [**lock-manager**](https://github.com/abap2UI5-addons/lock-manager) wraps the lock logic in a reusable class — including stale-lock cleanup and a "locked by X since…" message for the user. Install it like any other [add-on](../../resources/addons.md) and call it instead of writing the boilerplate yourself.
143
+
144
+
#### Choosing a Strategy
145
+
```
146
+
Does the app edit data at all?
147
+
├── No → render as read-only
148
+
└── Yes
149
+
├── A released, draft-enabled SAP BO already covers this object?
150
+
│ └── RAP Drafts
151
+
├── Need "locked by X" feedback at open?
152
+
│ ├── Few users, GUI-like feel → Stateful Session
153
+
│ └── Many users → Soft Lock + save guard
154
+
├── A lock-manager add-on available for your platform?
155
+
│ └── Lock-Manager Add-on
156
+
└── Default high-scale stateless editing
157
+
└── Combined (Lock at Save + Optimistic Check)
158
+
```
159
+
160
+
For the underlying concepts and trade-offs of statefulness, see [Statefulness, Locks](../../advanced/stateful.md).
0 commit comments