11CLASS kernel_lock_concurrent DEFINITION PUBLIC .
22 PUBLIC SECTION .
3+ CLASS-METHODS class_constructor.
4+
5+ CLASS-METHODS enqueue
6+ IMPORTING
7+ input TYPE any
8+ table_name TYPE string
9+ enqueue_name TYPE string
10+ EXCEPTIONS
11+ foreign_lock
12+ system_failure.
13+
14+ CLASS-METHODS dequeue
15+ IMPORTING
16+ table_name TYPE string
17+ enqueue_name TYPE string
18+ input TYPE any .
19+
20+ TYPES : BEGIN OF ty_cleanup,
21+ valid_locks TYPE i ,
22+ cleaned_locks TYPE i ,
23+ END OF ty_cleanup.
24+ CLASS-METHODS cleanup_locks
25+ RETURNING
26+ VALUE (rs_result ) TYPE ty_cleanup.
27+ PRIVATE SECTION .
28+ CLASS-METHODS build_lock_key
29+ IMPORTING
30+ input TYPE any
31+ table_name TYPE string
32+ RETURNING
33+ VALUE (rv_lock_key ) TYPE kernel_locks-lock_key.
334ENDCLASS .
435
536CLASS kernel_lock_concurrent IMPLEMENTATION .
637
38+ METHOD class_constructor .
39+ cleanup_locks( ).
40+ ENDMETHOD .
41+
42+ METHOD cleanup_locks .
43+ SELECT * FROM kernel_locks INTO TABLE @DATA (lt_locks ) ORDER BY PRIMARY KEY ##SUBRC_OK .
44+ LOOP AT lt_locks INTO DATA (ls_lock ).
45+ DATA (lv_exists ) = lcl_advisory=>exists( lcl_key=>encode( ls_lock-lock_key ) ).
46+ IF lv_exists = abap_true .
47+ rs_result-valid_locks = rs_result-valid_locks + 1 .
48+ ELSE .
49+ DELETE FROM kernel_locks WHERE table_name = @ls_lock-table_name AND lock_key = @ls_lock-lock_key.
50+ rs_result-cleaned_locks = rs_result-cleaned_locks + 1 .
51+ ENDIF .
52+ ENDLOOP .
53+ ENDMETHOD .
54+
55+ METHOD build_lock_key .
56+
57+ DATA lr_dref TYPE REF TO data .
58+ DATA lo_structdescr TYPE REF TO cl_abap_structdescr.
59+ DATA lv_string TYPE string .
60+
61+ FIELD-SYMBOLS <lg_row> TYPE any .
62+
63+ CREATE DATA lr_dref TYPE (table_name).
64+ ASSIGN lr_dref->* TO <lg_row> .
65+
66+ lo_structdescr ?= cl_abap_typedescr=>describe_by_data( <lg_row> ).
67+ ASSERT lo_structdescr IS NOT INITIAL .
68+
69+ LOOP AT lo_structdescr->components INTO DATA (ls_component ).
70+ WRITE '@KERNEL lv_string.set(input[ls_component.get().name.get().toLowerCase().trimEnd()] || "");' .
71+
72+ ASSIGN COMPONENT ls_component-name OF STRUCTURE <lg_row> TO FIELD-SYMBOL (<lv_row_field> ).
73+ ASSERT sy -subrc = 0 .
74+ <lv_row_field> = lv_string.
75+ ENDLOOP .
76+
77+ rv_lock_key = <lg_row> .
78+
79+ ENDMETHOD .
80+
81+ METHOD enqueue .
82+
83+ DATA ls_lock_row TYPE kernel_locks.
84+
85+ *******************
86+
87+ DATA (lv_lock_key ) = build_lock_key(
88+ input = input
89+ table_name = table_name ).
90+ ASSERT lv_lock_key IS NOT INITIAL .
91+
92+ ls_lock_row-table_name = table_name.
93+ ls_lock_row-lock_key = lv_lock_key.
94+ ls_lock_row-username = sy -uname .
95+ GET TIME STAMP FIELD ls_lock_row-timestamp.
96+ ls_lock_row-hostname = sy -host .
97+ ls_lock_row-lock_mode = '' .
98+ ls_lock_row-lock_name = enqueue_name.
99+
100+ TRY .
101+ lcl_advisory=>lock( lcl_key=>encode( ls_lock_row-lock_key ) ).
102+ CATCH lcx_advisory_lock_failed.
103+ RAISE foreign_lock.
104+ ENDTRY .
105+
106+ INSERT kernel_locks FROM @ls_lock_row.
107+ ASSERT sy -subrc = 0 .
108+
109+ ENDMETHOD .
110+
111+ METHOD dequeue .
112+
113+ DATA (lv_lock_key ) = build_lock_key(
114+ input = input
115+ table_name = table_name ).
116+
117+ TRY .
118+ lcl_advisory=>lock( lcl_key=>encode( lv_lock_key ) ).
119+ CATCH lcx_advisory_lock_failed.
120+ " it doesnt have the lock, or another session has the lock
121+ RETURN .
122+ ENDTRY .
123+
124+ DELETE FROM kernel_locks WHERE table_name = table_name AND lock_key = lv_lock_key.
125+
126+ " advisory locks stack,
127+ lcl_advisory=>unlock( lcl_key=>encode( lv_lock_key ) ).
128+ lcl_advisory=>unlock( lcl_key=>encode( lv_lock_key ) ).
129+ ENDMETHOD .
130+
7131ENDCLASS .
0 commit comments