[转帖]ORACLE等待事件:enq: TX - row lock contention
https://www.cnblogs.com/kerrycode/p/5887150.html
enq: TX - row lock contention等待事件,这个是数据库里面一个比较常见的等待事件。enq是enqueue的缩写,它是一种保护共享资源的锁定机制,一个排队机制,先进先出(FIFO)。enq: TX - row lock contention等待事件,OACLE将其归类为application级别的等待事件。有些场景是因为应用逻辑设计不合理造成的。下面我们看看enq: TX - row lock contention的英文介绍:
This wait indicates time spent waiting for a TX lock, typically due to waiting to gain access to a row in a table that is currently locked by that transaction. The TX lock waited on is "TX-P2RAW-P3RAW" and the object / row that triggered the wait can usually be found in the ROW_WAIT_* columns of V$SESSION for the waiting session.
A TX lock is acquired when a transaction initiates its first change and is held until the transaction does a COMMIT or ROLLBACK. It is used mainly as a queuing mechanism so that other sessions can wait for the transaction to complete. The lock name (ID1 and ID2) of the TX lock reflect the transaction ID of the active transaction.
下面我们模拟一下enq: TX - row lock contention等待事件出现的场景,希望能对这个等待事件有较深的理解,主要参考了官方文档 ID 62354.1
1: Waits due to Row being locked by an active Transaction
这个是因为不同的session同时更新或删除同一个记录。例如,会话1持有row level lock,会话2在等待这个锁释放。准备测试环境和数据
SQL> create table test
2 ( id number(10),
3 name varchar2(16)
4 ) ;
Table created.
SQL> insert into test
2 values(1001, 'kk');
1 row created.
SQL> insert into test
values(1002, 'tttt')
1 row created.
SQL> commit;
Commit complete.
SQL>
会话1(会话ID为75)更新某一行
SQL> select sid from v$mystat where rownum =1;
SID
----------
75
SQL> update test set name='ken' where id=1001;
1 row updated.
SQL>
会话2(会话ID为200)也更新这一行(删除亦可)
SQL> select sid from v$mystat where rownum=1;
SID
----------
200
SQL> update test set name='kerry' where id=1001; --一直被阻塞
在会话3中查看对应的会话、锁以及等待相关信息,这些SQL各
SQL> col type for a32;
SQL> SELECT sid,
2 type,
3 id1,
4 id2,
5 lmode,
6 request
7 FROM v$lock
8 WHERE type = 'TX';
SID TYPE ID1 ID2 LMODE REQUEST
---------- -------------------------------- ---------- ---------- ---------- ----------
200 TX 655385 2361 0 6
75 TX 655385 2361 6 0
SQL> COL event FOR a36;
SQL> SELECT sid,
2 Chr(Bitand(p1, -16777216) / 16777215)
3 || Chr(Bitand(p1, 16711680) / 65535) "name",
4 ( Bitand(p1, 65535) ) "mode",
5 event,
6 sql_id,
7 final_blocking_session
8 FROM v$session
9 WHERE event LIKE 'enq%';
SID name mode EVENT SQL_ID FINAL_BLOCKING_SESSION
---------- -------- ---------- ------------------------------------ ------------- ----------------------
200 TX 6 enq: TX - row lock contention cz4tvs78skhus 75
SQL> COL wait_class FOR A32;
SQL> SELECT inst_id,
2 blocking_session,
3 sid,
4 serial#,
5 wait_class,
6 seconds_in_wait
7 FROM gv$session
8 WHERE blocking_session IS NOT NULL
9 ORDER BY blocking_session;
INST_ID BLOCKING_SESSION SID SERIAL# WAIT_CLASS SECONDS_IN_WAIT
---------- ---------------- ---------- ---------- -------------------------------- ---------------
1 75 200 12230 Application 179
SQL> COL TX FOR A24;
SQL> SELECT
2 sid, seq#, state, seconds_in_wait,
3 'TX-'||lpad(ltrim(p2raw,'0'),8,'0')||'-'||lpad(ltrim(p3raw,'0'),8,'0') TX,
4 trunc(p2/65536) XIDUSN,
5 trunc(mod(p2,65536)) XIDSLOT,
6 p3 XIDSQN
7 FROM v$session_wait
8 WHERE event='enq: TX - row lock contention';
SID SEQ# STATE SECONDS_IN_WAIT TX XIDUSN XIDSLOT XIDSQN
---------- ---------- ------------------- --------------- ------------------------ ---------- ---------- ----------
200 46 WAITING 203 TX-000A0019-00000939 10 25 2361
SQL> col event for a36
SQL> col username for a10
SQL> col sql_fulltext for a80
SQL> SELECT g.inst_id,
2 g.sid,
3 g.serial#,
4 g.event,
5 g.username,
6 g.sql_hash_value,
7 s.sql_fulltext
8 FROM gv$session g,
9 v$sql s
10 WHERE g.wait_class = 'Application'
11 AND g.sql_hash_value = s.hash_value;
INST_ID SID SERIAL# EVENT USERNAME SQL_HASH_VALUE SQL_FULLTEXT
---------- ---------- ---------- ----------------------------- ----------- ------------- ---------------------------------
1 200 12230 enq: TX - row lock contention TEST 3515433816 update test set name='kerry' where id=1001
SQL> col type for a12;
SQL> select /*+rule*/
2 inst_id,
3 decode(request, 0, 'holder', 'waiter') role,
4 sid,
5 type,
6 request,
7 lmode,
8 block,
9 ctime,
10 id1,
11 id2
12 from gv$lock
13 where (id1, id2, type) in
14 (select id1, id2, type from gv$lock where request >0)
15 order by ctime desc ,role;
INST_ID ROLE SID TYPE REQUEST LMODE BLOCK CTIME ID1 ID2
---------- ------ ---------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
1 holder 75 TX 0 6 1 255 655385 2361
1 waiter 200 TX 6 0 0 245 655385 2361

此时只能等待持有锁的会话commit或者rollback。 通常为会话1在某行上执行 update/delete 未提交,会话2对同一行数据进行 update/delete,或其它原因(例如SQL性能差)造成的锁释放速度缓慢或网络问题,都会造成后续的会话进入队列等待。
2:Waits due to Unique or Primary Key Constraint Enforcement
表上存在主键或唯一索引,会话1插入一个值(未提交),会话2同时或随后也插入同样的值;会话提交后1,enq: TX - row lock contention消失。
SQL> drop table test purge;
Table dropped.
SQL> create table test
2 (
3 id number(10),
4 name varchar(16),
5 constraint pk_test primary key(id)
6 );
Table created.
会话1(会话ID为8)
SQL> insert into test values(1000, 'kerry');
1 row created.
会话2(会话ID为14)
SQL> insert into test values(1000,'jimmy');
会话3 在会话3中查看对应的会话、锁、以及等待信息
SQL> col type for a32;
SQL> SELECT sid,
2 type,
3 id1,
4 id2,
5 lmode,
6 request
7 FROM v$lock
8 WHERE type = 'TX';
SID TYPE ID1 ID2 LMODE REQUEST
---------- -------------------------------- ---------- ---------- ---------- ----------
14 TX 589835 2213 0 4
14 TX 393232 2160 6 0
8 TX 589835 2213 6 0
SQL> col event for a40
SQL> col username for a10
SQL> col sql_fulltext for a80
SQL> SELECT g.inst_id,
2 g.sid,
3 g.serial#,
4 g.event,
5 g.username,
6 g.sql_hash_value,
7 s.sql_fulltext
8 FROM gv$session g,
9 v$sql s
10 WHERE g.wait_class = 'Application'
11 AND g.sql_hash_value = s.hash_value;
INST_ID SID SERIAL# EVENT USERNAME SQL_HASH_VALUE SQL_FULLTEXT
---------- ---------- ---------- ----------------------------- ---------- -------------- ----------------------
1 14 13392 enq: TX - row lock contention TEST 874051616 insert into test values(1000,'jimmy')
SQL> col type for a12;
SQL> select /*+rule*/
2 inst_id,
3 decode(request, 0, 'holder', 'waiter') role,
4 sid,
5 type,
6 request,
7 lmode,
8 block,
9 ctime,
10 id1,
11 id2
12 from gv$lock
13 where (id1, id2, type) in
14 (select id1, id2, type from gv$lock where request >0)
15 order by ctime desc ,role;
INST_ID ROLE SID TYPE REQUEST LMODE BLOCK CTIME ID1 ID2
---------- ------------ ---------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
1 holder 8 TX 0 6 1 92 589835 2213
1 waiter 14 TX 4 0 0 70 589835 2213
会话1(会话ID为8)提交事务后
SQL> insert into test values(1000, 'kerry');
1 row created.
SQL> commit;
会话2(会话ID为14)遇到ORA-00001错误提示
SQL> insert into test values(1000,'jimmy');
insert into test values(1000,'jimmy')
*
ERROR at line 1:
ORA-00001: unique constraint (TEST.PK_TEST) violated
这个在ORACLE 10g以及以上版本都无法测试(Oracle 9i可以测试),因为ORACLE 10g中,对于单个数据块,Oracle缺省最大支持255个并发,MAXTRANS参数在ORACLE 10g以及以上版本被废弃了,即使你使用下面SQL指定了maxtrans为1, 但是你查看表的定义,你会发现maxtrans依然为255。
SQL> drop table test purge;
Table dropped.
SQL> create table test
2 (
3 id number(10),
4 name varchar(16)
5 ) initrans 1 maxtrans 1;
Table created.
所以这个场景只会发生在ORACLE 9i的版本中或是并发非常高的系统当中。
Waits due to rows being covered by the same BITMAP index fragment
这个源于位图索引的特性,更新位图索引的一个键值,会指向多行记录,所以更新一行就会把该键值指向的所有行锁定
SQL> create table employee
2 (
3 employee_id number(10),
4 employee_name nvarchar2(24),
5 sex varchar2(6)
6 );
Table created.
SQL> create bitmap index idx_employee_bitmap on employee(sex);
Index created.
SQL> insert into employee
2 select 1000, 'kerry', 'female' from dual union all
3 select 1001, 'jimmy', 'female' from dual;
2 rows created.
SQL> commit;
Commit complete.
SQL>
会话1:
SQL> update employee set sex='male' where employee_id=1000;
1 row updated.
会话2:
SQL> update employee set sex='male' where employee_id=1001;
会话3:
SQL> col type for a32;
SQL> SELECT sid,
2 type,
3 id1,
4 id2,
5 lmode,
6 request
7 FROM v$lock
8 WHERE type = 'TX';
SID TYPE ID1 ID2 LMODE REQUEST
---------- -------------------------------- ---------- ---------- ---------- ----------
14 TX 589836 2211 0 4
14 TX 131096 2204 6 0
8 TX 589836 2211 6 0
SQL> col event for a40
SQL> col username for a10
SQL> col sql_fulltext for a80
SQL> SELECT g.inst_id,
2 g.sid,
3 g.serial#,
4 g.event,
5 g.username,
6 g.sql_hash_value,
7 s.sql_fulltext
8 FROM gv$session g,
9 v$sql s
10 WHERE g.wait_class = 'Application'
11 AND g.sql_hash_value = s.hash_value;
INST_ID SID SERIAL# EVENT USERNAME SQL_HASH_VALUE SQL_FULLTEXT
---------- ---------- ---------- ------------------------------ ---------- -------------- ---------------------------------
1 14 13392 enq: TX - row lock contention EST 2418349426 update employee set sex='male' where employee_id=1001
SQL> col type for a12;
SQL> select /*+rule*/
2 inst_id,
3 decode(request, 0, 'holder', 'waiter') role,
4 sid,
5 type,
6 request,
7 lmode,
8 block,
9 ctime,
10 id1,
11 id2
12 from gv$lock
13 where (id1, id2, type) in
14 (select id1, id2, type from gv$lock where request >0)
15 order by ctime desc ,role;
INST_ID ROLE SID TYPE REQUEST LMODE BLOCK CTIME ID1 ID2
---------- ------------ ---------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
1 holder 8 TX 0 6 1 116 589836 2211
1 waiter 14 TX 4 0 0 76 589836 2211
SQL>
其它场景
There are other wait scenarios which can result in a SHARE mode wait for a TX lock but these are rare compared to the examples given above.
Example:
If a session wants to read a row locked by a transaction in a PREPARED state then it will wait on the relevant TX lock in SHARE mode (REQUEST=4). As a PREPARED transaction should COMMIT , ROLLBACK or go to an in-doubt state very soon after the prepare this is not generally noticeable.
例如,表存在主外键读情况,主表不提交,子表那么必须进行等待.
初始化测试表
SQL> create table employee( employee_id number, employee_name varchar(12), depart_id number);
Table created.
SQL> create table department(depart_id number primary key, depart_name varchar2(24));
Table created.
会话1:
SQL> select sid from v$mystat where rownum=1;
SID
----------
75
SQL> insert into department values(1000, 'sales');
1 row created.
会话2:
SQL> select sid from v$mystat where rownum=1;
SID
----------
200
SQL> insert into employee values(1024, 'kerry', 1000); --一直挂起,直到会话1提交
会话3
SQL> show user;
USER is "SYS"
SQL> select sid from v$mystat where rownum=1;
SID
----------
73
SQL> col type for a12;
SQL> select /*+rule*/
2 inst_id,
3 decode(request, 0, 'holder', 'waiter') role,
4 sid,
5 type,
6 request,
7 lmode,
8 block,
9 ctime,
10 id1,
11 id2
12 from gv$lock
13 where (id1, id2, type) in
14 (select id1, id2, type from gv$lock where request >0)
15 order by ctime desc ,role;
INST_ID ROLE SID TYPE REQUEST LMODE BLOCK CTIME ID1 ID2
---------- ------ ---------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
1 holder 75 TX 0 6 1 197 458758 2371
1 waiter 200 TX 4 0 0 97 458758 2371
SQL> COL TX FOR A24;
SQL> SELECT
2 sid, seq#, state, seconds_in_wait,
3 'TX-'||lpad(ltrim(p2raw,'0'),8,'0')||'-'||lpad(ltrim(p3raw,'0'),8,'0') TX,
4 trunc(p2/65536) XIDUSN,
5 trunc(mod(p2,65536)) XIDSLOT,
6 p3 XIDSQN
7 FROM v$session_wait
8 WHERE event='enq: TX - row lock contention';
SID SEQ# STATE SECONDS_IN_WAIT TX XIDUSN XIDSLOT XIDSQN
---------- ---------- ------------------- --------------- ------------------------ ---------- ---------- ----------
200 108 WAITING 145 TX-00070006-00000943 7 6 2371
SQL>
另外遇到enq: TX - row lock contention等待事件,单实例与RAC是否有所区别呢,如果是RAC,需要注意识别实例,否则很容易误杀其它会话?如果你查到了blocker,是不是应该直接kill掉呢? 这个必须要先征询客户的意见,确认之后才可以杀掉。不能因为外在压力和自己的急躁而擅自Kill会话。
在WAITEVENT: "enq: TX - row lock contention" Reference Note (文档 ID 1966048.1)中,也有一些比较有意思的SQL,可以参考一下
SQL> SELECT row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row#
2 FROM v$session
3 WHERE event='enq: TX - row lock contention'
4 AND state='WAITING';
ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW#
------------- -------------- --------------- -------------
75389 4 211 0
SQL> set linesize 240;
SQL> select owner, object_name from dba_objects
2 where object_id=75389;
OWNER OBJECT_NAME
------------------------------ ------------------
TEST TEST
SQL> SELECT
2 sid, seq#, state, seconds_in_wait,
3 'TX-'||lpad(ltrim(p2raw,'0'),8,'0')||'-'||lpad(ltrim(p3raw,'0'),8,'0') TX,
4 trunc(p2/65536) XIDUSN,
5 trunc(mod(p2,65536)) XIDSLOT,
6 p3 XIDSQN
7 FROM v$session_wait
8 WHERE event='enq: TX - row lock contention'
9 ;
SID SEQ# SECONDS_IN_WAIT TX XIDUSN XIDSLOT XIDSQN
---------- ---------- --------- --------------- --------------------------- ---------- ---------- ----------
137 27 WAITING 245 TX-00040012-000007E6 4 18 2022
在TX - row lock contention 的一些场景 这篇文章里面介绍了出现enq: TX - row lock contention等待的案例场景,网络问题、执行计划问题、应用问题等。在我遇到的实际案例当中,网络问题造成的'enq: TX - row lock contention'较多,因为现在大多数是无线网络,有些应用程序出现问题或网络出现问题过后,导致数据库中的进程依然在,但是对于的UPDATE等DML操作没有及时提交。从而出现较严重的enq: TX - row lock contention
诊断定位enq: TX - row lock contention等待事件
在官方文档 ID 62354.1里面,提供了一个根据AWR 快照ID查找那些段出现row lock 等待较多的SQL,这个也有一定的参考意义。
SELECT P.snap_id,
P.begin_interval_time,
O.owner,
O.object_name,
O.subobject_name,
O.object_type,
S.row_lock_waits_delta
FROM dba_hist_seg_stat S,
dba_hist_seg_stat_obj O,
dba_hist_snapshot P
WHERE S.dbid =O.dbid
AND S.ts# =O.ts#
AND S.obj# =O.obj#
AND S.dataobj# =O.dataobj#
AND S.snap_id =P.snap_id
AND S.dbid =P.dbid
AND S.instance_number =P.instance_number
AND S.row_lock_waits_delta > 0
AND P.snap_id BETWEEN <begin_snap> AND <end_snap>
ORDER BY 1,3,4;
一般最常用的还是AWR报告结合ASH报告来诊断、定位enq: TX - row lock contention等待事件,另外,在TX - row lock contention 的一些场景这篇分享文章中,对如何减少enq: TX - row lock contention等待做了一些总结,具体如下:
在一些事务频繁,并发较高的环境下,为了尽可能减少 TX - row lock contention 等待事件的发生,应当从应用设计到数据库多个层面进行考虑。
应用层面:
1、约束通常是为了保证数据完整性,在并发场景下,应充分考虑事务进行的逻辑顺序,避免多个会话事务交叉进行,触发约束冲突在事务级别发生竞争;
2、要提高并发效率,应当尽可能拆分大事务为小事务,提高 tx enqueue 锁的获取释放速度;
3、如果要使用悲观锁(for update),应尽可能减少锁定的行范围;
数据库层面:
1、在 dml 频繁的表上建立适当的索引,提高 SQL 执行的效率,减少 tx enqueue 锁持有的时间;避免全表扫描这种,容易造成 IO 开销巨大,热块竞争,会话堆积的访问方式。
2、在 dml 频繁的表上不应使用位图索引;
3、对于 dml 频繁的表,不应使用 IOT 表,物化视图等;
4、RAC 环境下,对于批量的 dml 操作,尽可能固定在单一节点,尽量降低网络开销、集群竞争、一致性块获取和日志刷盘等带来的影响。
参考资料:
https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=521417992978367&id=62354.1&displayIndex=1&_afrWindowMode=0&_adf.ctrl-state=1d01vq0378_227
http://mp.weixin.qq.com/s?__biz=MjM5MzExMTU2OQ==&mid=2650603515&idx=1&sn=275956ad38d26168e44027336644e5a0&scene=2&srcid=0711qxhIykeqO278x7VZFx5k&from=timeline&isappinstalled=0#wechat_redirect
http://www.dbform.com/html/2015/2317.html
http://www.killdb.com/2015/07/13/%E5%85%B3%E4%BA%8Eenq-tx-row-lock-contention%E7%9A%84%E6%B5%8B%E8%AF%95%E5%92%8C%E6%A1%88%E4%BE%8B%E5%88%86%E6%9E%90.html
http://blog.chinaunix.net/uid-23284114-id-3390180.html
http://yunlongzheng.blog.51cto.com/788996/411205
[转帖]ORACLE等待事件:enq: TX - row lock contention的更多相关文章
- ORACLE AWR结合ASH诊断分析enq: TX - row lock contention
公司用户反馈一系统在14:00~15:00(2016-08-16)这个时间段反应比较慢,于是生成了这个时间段的AWR报告, 如上所示,通过Elapsed Time和DB Time对比分析,可以看出在这 ...
- ORACLE等待事件:enq: TX - row lock contention
enq: TX - row lock contention等待事件,这个是数据库里面一个比较常见的等待事件.enq是enqueue的缩写,它是一种保护共享资源的锁定机制,一个排队机制,先进先出(FIF ...
- enq: TX - row lock contention“等待事件的处理
enq: TX - row lock contention“等待事件的处理 session1: SQL> conn scott/triger Connected. SQL> CRE ...
- [Oracle] enq: TX - row lock contention 优化案例
依据开发反馈.近期每天早上7:30应用会报警.应用的日志显示数据库连接池满了.新的连接被拒绝. 首先.我做了ASH报告(报告区间:7:25 ~ 7:35),从ASH的等待事件发现enq: TX - r ...
- 大表建立索引引发enq: TX - row lock contention等待
今天要给一张日志表(6000w数据)建立索引,导致生产系统行锁部分功能卡住 create index idx_tb_cid on tb_login_log(user_id); 开始执行后大概花费了20 ...
- enq: TX - row lock contention故障处理一则
一个非常easy的问题,之所以让我对这个问题进行总结.一是由于没我想象的简单,在处理的过程中遇到了一些磕磕碰碰,甚至绕了一些弯路.二是引发了我对故障处理时的一些思考. 6月19日,下午5点左右.数据库 ...
- 记一则update 发生enq: TX - row lock contention 的处理方法
根据事后在虚拟机中复现客户现场发生的情况,做一次记录(简化部分过程,原理不变) 客户端1执行update语句 SQL> select * from test; ID NAME --------- ...
- 解决一则enq: TX – row lock contention的性能故障
上周二早上,收到项目组的一封邮件: 早上联代以下时间点用户有反馈EDI导入"假死",我们跟踪了EDI导入服务,服务是正常在跑,可能是处理的慢所以用户感觉是"假死" ...
- Tuning “enq:TX – row lock contention” events
enq是一种保护共享资源的锁定机制,一个排队机制 排它机制从一个事务的第一次改变直到rollback or commit 结束这个事务, TX等待mode是6,当一个session 在一个表的行级锁定 ...
- enq: TX - row lock contention 参数P1,P2,P3说明
enq: TX - row lock contention三个参数,例如,下面的等待事件 * P1 = name|mode <<<<<<< ...
随机推荐
- Pytest07-pytest.ini配置文件
1.pytest配置文件 固定名称:pytest.ini 作用域:当前目录及子目录 具体配置功能见下: [pytest] # 01 把命令行参数自动添加到这里 addopts = -s -v --ht ...
- 1、Flutter把内容单独抽离成一个组件
//代码块 importM import 'package:flutter/material.dart'; void main() { runApp( MaterialApp( theme ...
- 浏览器工作原理和实践(二)——JavaScript
<浏览器工作原理与实践>是极客时间上的一个浏览器学习系列,在学习之后特在此做记录和总结. 一.执行流程 实际上变量和函数声明在代码里的位置是不会改变的,而且是在编译阶段被 JavaScri ...
- KubeEdge和Kuiper“双剑合并”,轻松解决边缘流式数据处理
摘要:KubeEdge 是一个开源的边缘计算平台,它在Kubernetes原生的容器编排和调度能力之上,扩展实现了 云边协同.计算下沉.海量边缘设备管理.边缘自治等能力.KubeEdge还将通过插件的 ...
- 带你认识全新的华为云IoT路网数字化服务
摘要:随着通信技术的发展,交通领域提出以C-V2X车路协同技术来弥补单车智能存在的缺陷,从而推动智能驾驶.自动驾驶技术的成熟. 本文分享自华为云社区<带你全新认识华为云IoT路网数字化服务> ...
- 火山引擎 DataLeap:从短视频 APP 实践看如何统一数据指标口径
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 短视频正在成为越来越多人发现世界的窗口,其背后的创作者生态建设是各大短视频 APP 不可忽视的重要组成部分. 为了 ...
- Solon Aop 特色开发(4)Bean 扫描的三种方式
Solon,更小.更快.更自由!本系列专门介绍Solon Aop方面的特色: <Solon Aop 特色开发(1)注入或手动获取配置> <Solon Aop 特色开发(2)注入或手动 ...
- Solon 开发进阶
Solon 开发进阶 一.插件扩展机制 二.体外扩展机制 三.常用配置说明 四.启动参数说明 五.全局异常订阅 本系列在内核知识的基础上做进一步延申.主要涉及: 插件扩展体系 体外扩展体系 常用配置 ...
- ME51N 采购申请屏幕增强仅显示字段
1.业务需求 通过委外工单生成的采购申请,需要将自定义"图号"字段显示在采购申请中,且只用于显示即可 2.增强实现 增强表EBAN的结构CI_EBANDB 增强点CMOD:MERE ...
- 【第三方库】从编译到运行,轻松学会gflags库
gflags是Google开源的一个库,可以很方便地定义一些全局变量,并且可以从命令行设置他们的值,广泛应用于各个项目中以及自己平时的开发中.本期参考gflags的官方文档,简单直接介绍下怎么使用这个 ...