ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

052、帮助视图与锁视图

052、帮助视图与锁视图 调试一个报表取数异常愣是耗了整个下午。查到最后根源出在视图上——不是数据库表而是那种带关联条件的帮助视图。SE11里看着数据好好的一进程序就缺行或者重复。那时候你才会意识到对ABAP视图的理解还停留在“会建表”的层面是远远不够的。这篇笔记就说说帮助视图和锁视图这两个在开发中常被忽略、但在关键时刻卡脖子的东西。先说说帮助视图。它的本质不是用来取数给报表的而是给搜索帮助Search Help当数据源的。SE11里建帮助视图通常是用几个表做关联然后指定一个主表设置关联条件定义哪些字段是输出字段。很多人会误以为帮助视图跟数据库视图一样可以直接在OPEN SQL里查。这里踩过坑——帮助视图在ABAP里对应的类型是“H”你写SELECT * FROM 帮助视图名语法上能过但运行起来性能极差而且它走的是搜索帮助的内部逻辑不一定按你预期的关联方式返回数据。别这样写。要取数老老实实建数据库视图类型是“D”的那种或者干脆直接查透明表。帮助视图真正的作用是配合事务代码SE11里的“搜索帮助”功能让用户在F4输入框里能看到来自多张表的字段组合。比如物料主数据你要让用户按物料编码、工厂、库存地点三个字段一起模糊搜索这三个字段分散在不同的表里这时候用帮助视图把MARA、MARC、MARD关联起来定义成搜索帮助的“基本数据源”。这里有一个关键点帮助视图的关联条件一定要尽量用主键或索引字段否则F4帮助一打开后台执行的就是全表扫描生产系统直接卡死。你别问我怎么知道的当年一个整单搜索用了一个帮助视图关联字段没建索引用户一点搜索数据库CPU瞬间打满DBA半夜打电话骂人。再记住一点帮助视图里的记录是支持“重复值”的。因为它是多表关联关联条件如果是一对多返回的记录就会重复。这在搜索帮助场景下没问题用户会看到多条相同的关键字段值然后靠其他字段区分。但如果你是拿来当数据源做报表重复记录会让你SUM翻倍。所以代码里用了帮助视图一定要DISTINCT或者GROUP BY除非你明确知道这个关联结果就是唯一的。说完帮助视图锁视图是另一个容易“静默出错”的地方。锁视图在SE11里其实不是真正意义上的数据库视图它是在ABAP数据字典里定义的一个“锁定逻辑”配合函数模块ENQUEUE_和DEQUEUE_使用。你创建锁视图时要指定锁表定义锁的字段通常是主键设置锁模式共享锁、排他锁。这里最容易犯的错是锁对象设了太多字段导致更新时锁冲突频繁。比如你只想锁单据头结果把行项目表也关联进锁视图那么只要有用户改单据体整个表头都被锁住其他会话只能干等。正确的做法是锁的粒度要尽可能小——能用单表主键锁住的绝不关联子表。还有一类坑是锁模式搞反。共享锁SHARED允许多个会话同时读取但阻止写排他锁EXCLUSIVE阻止其他会话读和写。有些新手做更新程序明明要防并发修改却用了共享锁结果两个用户同时进入编辑页面都能改同一张单据最后提交时后保存的覆盖先保存的。别问这种低级错误是否真实存在DBA那边有无数报警邮件就是被这种共享锁搞出来的。锁视图的关键使用场景是在程序里调用更新函数之前。比如你SAP MESSAGE到数据库表ZORDER先用ENQUEUE_EZORDER锁定ZORDER表的主键如果系统返回异常类型为“FOREIGN_LOCK”说明这个单正在被其他用户操作那就提示“数据正被处理请稍后再试”。这段时间不能省略。很多程序员偷懒直接MODIFY到表也不做锁操作等到两个业务员同时审批同一张销售订单时问题就来了——各自读出来的数据都是旧状态后提交的直接覆盖先提交的审批结论。这时候你再好的业务逻辑都救不回来。用锁视图还有一个性能方面的讲究。锁是通过ENQUEUE表实现的锁对象本身有有效期通常到程序结束或者显式DEQUEUE解锁。如果不做DEQUEUE长时间占用锁会阻塞其他事务。所以推荐在更新成功后立刻解锁放到PBO里无所谓放在功能模块出口里不如放在PAI里总之要快。而且要注意当程序发生异常时系统会自动释放锁但如果你捕获了异常然后继续跑其他逻辑锁不会自动释放这就得在CATCH块里手动DEQUEUE否则这个锁会一直挂到会话结束。我写过那种程序白天跑得好好的凌晨批处理一跑因为某个异常吞掉了解锁结果后续批次全部卡在同一把锁上。教训就是DEQUEUE必须和ENQUEUE成对出现比事务提交还要优先安排。辅助的话锁视图还可以配合“RFC”使用比如远程调用其他系统时先锁远程表再更新然后UNLOCK。不过跨系统锁要考虑锁所有者的问题Session ID不同ENQUEUE表里记录的用户名、主机名都对不上很容易死锁。所以跨系统的锁要么不用要么用全局事务管理器去协调。最后给点个人经验。第一在SE11里建锁视图之前先想想这个锁是不是真的需要跨表联锁。如果你只是更新表头就锁表头主键如果更新了行项目那要锁每一条被改的行而不是整个表。第二帮助视图里的字段命名要有统一前缀因为搜索帮助的搜索结果展示是用视图字段名的标签的名字起得像ZZ1、ZZ2这种用户在F4里看着一脸懵。第三无论是帮助视图还是锁视图都要和权限检查配合。帮助视图本身不会做权限过滤如果某些字段不能让用户看到得在搜索帮助的“用户对话”里加入权限检查逻辑别指望视图帮你挡数据。调试定位问题的时候不妨用事务代码SE93查看程序调用链或者直接ST05跟踪数据库操作看看是不是有隐藏在帮助视图里的冗余关联。锁的问题SM12能看到当前锁对象列表哪个用户锁了什么一目了然。这些工具比你看十遍代码都有用。就写到这里下一章聊搜索帮助的底层实现再说说F4字段匹配和动态值限制那些事。
返回列表