【SAP Abap】X-DOC:SE37 - ABAP 功能模块之更新模块(Function Module 之 Update module)

news2024/11/24 15:03:09

【SAP Abap】X-DOC:SE37 - ABAP 功能模块之更新模块(Function Module 之 Update module)

  • 1、简介
    • 1.1、什么是更新函数
    • 1.2、更新函数的类型
    • 1.3、更新函数的参数要求
    • 1.4、更新函数的调用方式
    • 1.5、更新函数的调试方式
    • 1.6、更新任务的执行模式
    • 1.7 更新任务的执行过程
    • 1.8、更新任务的执行监控
    • 1.8、注意事项
  • 2 、应用
    • 2.1、执行顺序的应用
    • 2.2、更新事务的应用
    • 2.3、隐式增强的应用
    • 2.4、应用更新进程机制
  • 3、示例
    • 3.0、系统示例
    • 3.1、测试用表及函数
    • 3.2、Demo1(同步、异步、本地)
    • 3.3、Demo2(V1、V2优先级)

1、简介

1.1、什么是更新函数

在SE37中,创建的功能模块,勾选了处理类型为“更新模块”后,即为更新函数。
在这里插入图片描述
SAP 的 Update Module 函数(又称为更新函数),主要用于对话或报表程序中实现同步或异步更新数据库的功能。对于需要更新数据库,但又对主程序的运行不产生影响(即更新成功与否不影响主程序的正常执行)的操作,可以使用更新任务(即Update Module函数的IN UPDATE TASK)来实现。更新模块在程序中使用 CALL FUNCTION IN UPDATE TASK 调用,此时函数并不会立即执行,而是在执行到COMMIT WORK 时才会触发执行。

典型的SAP 系统配置包括对话任务和更新任务,对话任务处理与用户的交互会话,更新任务专用于执行数据库更新。更新函数用于在对话任务和更新任务中执行更新,对话任务更新是同步更新,更新任务更新是异步更新(例外:用 COMMIT WORK AND WAIT 触发更新任务功能时,它是同步更新)。

在事务内部,对于每条 COMMIT WORK 语句可以调用一个或多个更新任务功能模块。在报表中,也可以通过 COMMIT WORK 语句显式提交更新任务功能模块。更新函数只能在 COMMIT WORK 或 ROLLBACK WORK 处才会被执行,一般调用事务内部,在完成一个 SAP LUW时都有一个隐式的 COMMIT WORK 功能,故不用再明确提交;而在报表事务中,需要显式使用 COMMIT WORK 功能进行更新函数的提交。

1.2、更新函数的类型

更新函数分为V1和V2两类,决定了更新函数执行的先后顺序。只有当V1请求执行成功之后才会处理V2请求,所以V2类型的数据库更新操作一般都是紧接着V1类型的数据库更新操作之后进行的。V1 类型的 UPDATE MODULE 分可重新启动和不可重新启动两种。V2类型的当发生错误的时候总是可以重新启动,再次处理。

V1类型
(1)立即开始(可重启),在同一个 更新事务(SAP LUW)中运行的优先级为高,当出现错误时更新任务可以重新启动这些功能。
(2)立即启动(不可重启),在同一个更新事务(SAP LUW)中运行的优先级为高,但不能由更新任务重新启动这些功能。
V2类型
(1)延迟启动(可重启),在同一个更新事务(SAP LUW)中运行的优先级为低,当出现错误时更新任务可以重新启动这些功能。
(2)集中运行(collective run),SAP内部使用,该类型的V2请求并不会直接执行,而需要在程序 RSM13005 被调用之后才执行。

1.3、更新函数的参数要求

(1)可用参数类型
因为更新任务功能模块不能报告其结果,因此不允许有结果参数(EXPORTING,CHANGING),只能有输入参数(IMPORTING)和表参数(TABLES),以及例外(EXCEPTIONS)。如果创建传出参数(EXPORTING)和修改参数(CHANGING),程序将检查不通过。
(2)传入参数设置
在更新函数中传入参数(IMPORTING)只允许使用
值传递方式
,且必须指定参数类型,对应的参数须使用参照字段进行定义。
(3)传出参数设置
更新函数可以有TABLE参数,并且该表格需要有对应的参考结构。一般使用TABLE参数用于获取更新执行成功与否的反馈消息(RETURN表格);或者传入用于查询数据的参考内表(尽量不更改传入内表的数据)。
(4)源代码
UPDATE MODULE里包含实际的数据库更新语句。

1.4、更新函数的调用方式

将函数设置为更新模块后,调用时既可以将该函数定义到更新任务中,也可以作为普通函数进行调用。
(1)作为普通函数调用
使用普通函数的 CALL FUNCTION 的调用方式实现即可,此时该函数仅作为普通函数执行,不作为更新函数。

  CALL FUNCTION 'YFM_UPDATE_01_V1'
    EXPORTING
      iv_tag = '1、Normal FM'.

(2)作为更新函数调用
作为更新函数调用,则需要在普通函数的 CALL FUNCTION 调用语句上附加 IN UPDATE TASK,则更新函数将在一个 SAP LUW 执行到 COMMIT WORK 处时,系统统一执行。

  CALL FUNCTION 'YFM_UPDATE_01_V1' IN UPDATE TASK
    EXPORTING
      iv_tag    = '2、Update FM, By Import'.

1.5、更新函数的调试方式

三类函数的调试存在很大的区别。普通函数需要通过内部断点进行调试,RFC函数需要设置调试外部请求用户,通过外部断点进行调试。
更新函数需要更改调试器设置,开启“更新调试”模式(如果勾选’提交’按钮,只会在本次登录中有效。如果勾选’保存’按钮,下次登录后该调试功能依旧有效。),才能在程序处理完 COMMIT WORK 语句之后,自动进入更新函数调试界面。
在这里插入图片描述

1.6、更新任务的执行模式

(1)异步模式,不同进程(COMMIT WORK)
在这个模式下,对话程序会用一个 COMMIT WORK 来关闭 LUW,更新程序被 COMMIT 触发并开始运行来处理这些请求。此时对话程序和更新程序在各自的进程中运行,对话程序会继续运行,不会等待更新程序结束。
当数据库更新花费比较长的时间,用户对话需要较少的响应时间,异步更新显得比较重要。在对话处理中,异步更新是标准的方式,对话程序一般会采取异步更新方式。

(2)同步模式,不同进程(COMMIT WORK AND WAIT)
可以用 COMMIT WORK AND WAIT 语句来触发一个同步更新,对话程序会等待更新程序结束再进行下一步的处理。对于同步更新,可以使用SY-SUBRC来检查同步更新的执行情况,在程序等待更新程序执行的过程中,对话程序的 DIALOG WORK PROCESS 被释放,当更新结束之后,系统重新为对话程序分配一个新的空闲的 DIALOG WORK PROCESS 做下一步的处理。
如果后续处理或者对话程序的结束需要依靠更新的结果,这个时候要用同步模式。

(3)本地模式,同一进程(SET UPDATE TASK LOCAL)
使用 SET UPDATE TASK LOCAL 语句来使 UPDATE MODULE 在本地执行,同样的用 COMMIT WORK 来关闭 SAP LUW,不管 COMMIT是否 WAIT,更新会在同一个 DIALOG WORK PROCESS 中进行(即同一个SAP LUW),对话程序等待更新完成。当LOCAL UPDATE完成之后,会提交一个 DB COMMIT,对话程序也得以继续执行;如果更新执行有错误,并且其中一个 UPDATE MODULE 发出一个终止程序的消息(通知到请求用户),系统会执行一个自动的DB ROLLBACK来丢弃这个SAP LUW所有的改变,并且对话程序会终止,并弹出一个程序终止信息。
LOCAL UPDATE模式中,更新请求不会写到VBLOG表中,而是在MAIN MEMORY中,因为没有IO的访问,其速度要比同步和异步模式的快一点。LOCAL UPDATE只适合批量模式。
注:
① SET UPDATE TASK LOCAL只对一个LUW起作用,且必须在第一个update task注册之前申明,即如果多次调用COMMIT,就需要每次都在第一个update task之前申明SET UPDATE TASK LOCAL。
② 本地更新模式仅对V1类型请求起作用,V1请求将在MAIN MEMORY中创建的,V2类型的请求总是创建到LOG表中。

1.7 更新任务的执行过程

(1)DIALOG 程序获得用户要更新的数据,并把更新任务写到一个特殊的LOG表,表内的条目属于同一个请求类型,包含了稍后将要写到数据库的数据。一个 DIALOG 程序可以写多条数据到LOG表,写进LOG表里的条目属于同一个LUW。一个 SAP LUW 下的更新请求存储在同一个 UPDATE KEY 下,只有当程序执行到 COMMIT WORK 的时候,才会为这些请求创建一个抬头条目LOG HEADER,表示以上这些同样 UPDATE KEY 的属于同一个包,它们要么都被执行,要么都不被执行。
(2)DIALOG 程序通过 COMMIT 关闭 LUW(将LOG表的条目打包),并通知系统基本程序有一个包的数据需要更新。
(3)系统基本程序从LOG 表读取这个 LUW 的需要更新的数据,并把这些数据提供给系统更新程序。
(4)系统更新程序接受传输给它的数据,并更新数据库。
(5)如果更新程序运行成功,系统基本程序删除这个LUW在LOG表的所有数据;如果失败,保持LOG表的这些数据,并标记不成功。同时触发更新程序的用户会收到系统发的关于这个错误的消息。可以用SM13来检查LOG条目。

注:
(1)LOG表,ECC使用VBLOG这个簇表来实现,S4使用透明表VBHDR、VBMOD、VBDATA、VBERROR 来替代它,前端查看更新任务状态使用事务码 SM13。
(2)可以用参数rdisp/vbmail(1发,0不发)来控制错误时是否发E-MAIL和rdisp/vb_mail_user_list($ACTUSER代表创建更新数据的用户)来控制错误时发E-MAIL给谁。
(3)当丢弃当前SAP LUW的所有changes(比如结束TCODE),可以使用ROLLBACK WORK或者弹出一个A类型的MESSAGE,这两个语句都可以有以下的效果:
-删除写到该点之前的所有的change requests
-删除写到该点之前所有的锁
-丢弃当前DB LUW执行的changes
-丢弃所有使用POC形式登记的subroutines
(4)DIALOG 程序用_SCOPE = 2创建的锁会被传递到V1 更新任务中,在V1更新的结束,不管V1更新是否成功或者终止,都会把这些锁自动删除。因此,在DIALOG程序中不能显式的删除这些锁(太早),或者在UPDATE MODULE里删除(没必要)。

1.8、更新任务的执行监控

使用事务码 SM13 ,可以监控更新请求。
在这里插入图片描述
点击执行后存在两个更新任务。
在这里插入图片描述
第一行的STATUS为INITIAL表明程序还未执行(一般调试模式才可见);
第二行的STATUS为红色,表明程序执行过程有错误,可以点击进入更新函数列表。
在这里插入图片描述其中包含四个更新函数,分别为V2、V1类型:
根据V1,V2类型的区别(优先执行V1,待全部执行后再执行V2)。
程序首先执行V1类型的更新函数,V1函数执行成功后,更新函数列表如图所示,状态显示“已处理”,程序继续执行V2类型的更新函数;若V1类型的更新函数执行出错,则不再继续执行后续任务,直接进行更新事务回滚,同时标记更新任务列表中该记录为出错。
V2类型更新函数执行过程类似,若执行出错,则回滚V2类型的更新事务,同时标记该记录为出错;若全部执行成功,则在更新任务列表中该记录消失。
更新任务发生错误时,会向任务请求者发送一条消息提醒。
针对存在错误的更新函数,我们可通过点击更新任务列表详细查看报错的函数。
双击弹出提示框,可点击ABAP SHORT DUMP按钮查看详细报错信息。同样我们也可通过ST22查看报错记录。

1.8、注意事项

(1)在update task里不能使用commit work / rollback,否则会dump,尽量不要使用check, 避免检查失败不运行其他业务逻辑。
(2)使用update task可以控制出错时多个update module同时回滚。
(3)在update module中打断点是不会进去的,dump了也不会报出来,会把错误发到用户的收件箱。

2 、应用

更新函数的使用范围是很广泛,尤其在ERP与其他系统的接口功能设计时使用很方便。

2.1、执行顺序的应用

在功能封装中,对于系统表的增强字段更新,或是获取系统表的字段值,可以在系统BAPI或更新函数执行后增加一个V2类型的更新函数,因为系统先执行其自带的V1和V2类型的更新函数,然后再执行自定义的V2类型的更新函数,可以在同步模式WAIT后,实现对透明表的直接操作。

2.2、更新事务的应用

在ABAP的开发中,根据业务的需要,同时对后台多个数据表进行更新,为了保证数据的完整性、一致性,需要把这些操作写在同一个更新事务中,实现对数据的操作,要么全部成功,要么全部失败回滚。
又如自动过账程序,将过账的更新和对自定义表的更新操作,用一个更新模块来封装,通过这种方式确保操作都在更新进程中执行, 如果过账更新报错,会中断更新过程,自定义表也就不会更新了。

2.3、隐式增强的应用

在单据保存类增强项,可以在隐式增强中调用自建更新函数的方式来实现。

2.4、应用更新进程机制

尽量使用 IN UPATE TASK 提交自定义表的更新,应用系统的更新进程机制,如果存在更新错误,可以通过SM13查看报错的信息。

3、示例

3.0、系统示例

SAP 系统中,一些单据保存到数据库用的是 update mudule function。
命名是ME_UPDATE_* (业务说明)
例:
ME_UPDATE_REQUISITION PR save module
ME_UPDATE_INFORECORD 更新采购主记录数据
ME_UPDATE_AGREEMENT_PO 更新采购凭证
ME_UPDATE_SCHEDULE_EKPO 计划协议下达
ME_UPDATE_DELIVERY 更新采购凭证

3.1、测试用表及函数

(1)测试用表
在这里插入图片描述
(2)测试用函数
① YFM_UPDATE_01_V1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
② YFM_UPDATE_02_V1
在这里插入图片描述
③ YFM_UPDATE_03_V2
在这里插入图片描述
④ YFM_UPDATE_04_V2
在这里插入图片描述

FUNCTION yfm_update_01_v1.
*"----------------------------------------------------------------------
*"*"更新函数模块:
*"
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IV_A) TYPE  INT2 OPTIONAL
*"     VALUE(IV_B) TYPE  INT2 OPTIONAL
*"     VALUE(IV_OP) TYPE  CHAR1 OPTIONAL
*"     VALUE(IV_TAG) TYPE  YEF5 OPTIONAL
*"     VALUE(IV_ERRORX) TYPE  CHAR1 OPTIONAL
*"     VALUE(IV_SEC) TYPE  I DEFAULT 0
*"  TABLES
*"      IT_DATA STRUCTURE  YTTEST OPTIONAL
*"      ET_DATA STRUCTURE  ZSBC003 OPTIONAL
*"  EXCEPTIONS
*"      ON_ZERO
*"----------------------------------------------------------------------

  DATA: lv_fm_name TYPE string VALUE 'V1-01'.
  WAIT UP TO iv_sec SECONDS.    "<---- a database commit is triggered (except during updates).
  DATA ls_yttest TYPE yttest.
  IF iv_errorx EQ 'X'.
    ls_yttest = it_data[ 0 ].   " Trrigger A Dump
  ENDIF.

  DATA p_no type yeitemo.
  PERFORM get_no CHANGING p_no.

  IF it_data[] IS NOT INITIAL.
    ls_yttest = VALUE #( it_data[ 1 ] OPTIONAL ).
    ls_yttest-itemo = p_no.
    ls_yttest-yf4 = lv_fm_name.
    ls_yttest-ydatetime = |{ sy-datum }{ sy-uzeit }|.
  ELSE.
    GET TIME STAMP FIELD DATA(lv_timestamp).
    ls_yttest = VALUE yttest(
      itemo = p_no
      yf1 = iv_a
      yf2 = iv_b
      yf3 = iv_op
      yf4 = lv_fm_name
      yf5 = iv_tag
      ydatetime = |{ sy-datum }{ sy-uzeit }|
    ).
  ENDIF.
  MODIFY yttest FROM ls_yttest.

ENDFUNCTION.

*&---SNRO取值编号
FORM get_no CHANGING p_no.
  CALL FUNCTION 'NUMBER_RANGE_ENQUEUE'
    EXPORTING
      object           = 'YITEMO'
    EXCEPTIONS
      foreign_lock     = 1
      object_not_found = 2
      system_failure   = 3
      OTHERS           = 4.
  IF sy-subrc = 0.                    "如果号码范围存在
    CALL FUNCTION 'NUMBER_GET_NEXT'   "将号码累加,获得下一个流水号
      EXPORTING
        nr_range_nr             = '01'
        object                  = 'YITEMO'
      IMPORTING
        number                  = p_no
      EXCEPTIONS
        interval_not_found      = 1
        number_range_not_intern = 2
        object_not_found        = 3
        quantity_is_0           = 4
        quantity_is_not_1       = 5
        interval_overflow       = 6
        buffer_overflow         = 7
        OTHERS                  = 8.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
         WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ELSE.
      CALL FUNCTION 'NUMBER_RANGE_DEQUEUE'
        EXPORTING
          object           = 'YITEMO'
        EXCEPTIONS
          object_not_found = 1
          OTHERS           = 2.
    ENDIF.
  ENDIF.
ENDFORM.
FUNCTION yfm_update_02_v1.
  ...
  DATA: lv_fm_name TYPE string VALUE 'V1-02'.
  ...
ENDFUNCTION.
FUNCTION yfm_update_03_v2.
  ...
  DATA: lv_fm_name TYPE string VALUE 'V2-01'.
  ...
ENDFUNCTION.
FUNCTION yfm_update_04_v2.
  ...
  DATA: lv_fm_name TYPE string VALUE 'V2-02'.
  ...
ENDFUNCTION.

3.2、Demo1(同步、异步、本地)

*&---------------------------------------------------------------------*
*& Report YZ_DEMO_CALL_UPDATE_FM
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT yz_demo_call_update_fm.
INCLUDE yz_demo_call_update_fm_f01.

DATA: gv_tag TYPE char50.

START-OF-SELECTION.
  "clear test data
  DELETE FROM yttest.

  "call normal fm, value can pass by constant
  CALL FUNCTION 'YFM_UPDATE_01_V1'
    EXPORTING
      iv_tag = '1、Normal FM'.

  " update fm will be called after commit,in the same dialog work process
  " must put before the first update fm in one sap luw
*SET UPDATE TASK LOCAL.
  " call update fm by import, value must pass by parameter ??
  " execute after commit in a new update work process
  PERFORM frm_call_update_fm USING 'YFM_UPDATE_01_V1' '2、Update FM, By Import' ''.

  "local
  PERFORM frm_add_data USING '3、Local'.

*COMMIT WORK.             "<---- End SAP LUW and start a new one
  WAIT UP TO 1 SECONDS.     "<---- a database commit is triggered (except during updates).
  "No wait may lead to cannot get number for update task(2Update FM, By Import*SET UPDATE TASK LOCAL.    " update fm will be called after commit,in the same dialog work process
  "call update fm by tables
  DATA: lt_data TYPE TABLE OF yttest.
  lt_data = VALUE #( (
      yf5 = '4、Update FM, By Tables'
      )
    ).
  CALL FUNCTION 'YFM_UPDATE_01_V1' IN UPDATE TASK
    EXPORTING
      iv_errorx = ''     " trrigger error, if run in update work process, an email will be sent
    TABLES
      it_data   = lt_data.

  DO 2 TIMES.                         " only trrigger once
    gv_tag = '5、Local, on Commit'.
    PERFORM frm_mod_data ON COMMIT.   " execute in the same dialog work process and before updata module
  ENDDO.

  "local
  PERFORM frm_add_data USING '6、Local'.

  gv_tag = '5、Local, on Commit, changed before commit'.      " effect in form on commit
  COMMIT WORK AND WAIT.       "<---- End SAP LUW and start a new one
  " Note:
  " Implicit Commit cannot trrigger the update fm
  " Explicit Commit can trrigger the update fm
  "   commit work, asynchronous with new update work process
  "   commit work and wait, synchronous with new update work process
  "   set update task local, synchronous with same dialog work process

  "show test data
  SELECT * FROM yttest INTO TABLE @DATA(lt_yttest).
  cl_demo_output=>display( lt_yttest ).

FORM frm_mod_data.
  PERFORM frm_add_data USING gv_tag.
ENDFORM.

3.3、Demo2(V1、V2优先级)

*&---------------------------------------------------------------------*
*& Report YZ_DEMO_CALL_UPDATE_FM
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT yz_demo_call_update_fm2.
INCLUDE yz_demo_call_update_fm_f01.

START-OF-SELECTION.
  "clear test data
  DELETE FROM yttest.

  "call update
  PERFORM frm_call_update_fm USING 'YFM_UPDATE_04_V2' '1、Update FM(V2-2)' ''.

  PERFORM frm_call_update_fm USING 'YFM_UPDATE_03_V2' '2、Update FM(V2-1)' ''.

  PERFORM frm_call_update_fm USING 'YFM_UPDATE_02_V1' '3、Update FM(V1-2)' ''.

  PERFORM frm_call_update_fm USING 'YFM_UPDATE_01_V1' '4、Update FM(V1-1)' ''.

  "local
  PERFORM frm_add_data USING '5、Local'.

  COMMIT WORK AND WAIT.   "<---- End SAP LUW and trrigger the three updata fm
  WAIT UP TO 1 SECONDS.   " wait for the result of v2 update fm

  "show test data
  SELECT * FROM yttest INTO TABLE @DATA(lt_yttest).
  cl_demo_output=>display( lt_yttest ).

原创文章,转载请注明来源-X档案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/530322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言——控制语句

目录 1. 分支语句1.1 if语句1.1.1 基本结构1.1.2 分层结构1.1.3 嵌套结构 1.2 switch case 语句 2.循环语句2.1 for循环2.1.1 基本结构2.1.2 嵌套结构2.1.3 变形 2.2 while循环2.3 do while循环2.4 死循环2.5 循环控制语句 控制语句即用来实现对程序流程的选择、循环、转向和返…

Shiro框架漏洞分析与复现

Shiro简介 Apache Shiro是一款开源安全框架&#xff0c;提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用&#xff0c;同时也能提供健壮的安全性&#xff0c;可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。 1、Shiro反序列…

Linux下的线程(线程的同步与互斥)

目录 Linux下线程创建函数pthread_ create() 线程的等待函数pthread_ join() 线程终止 函数pthread exit() 函数pthread_cancel() 分离线程pthread_detach() 线程间的互斥 线程间同步 死锁 进程和线程 线程和进程是一对有意义的概念&#xff0c;主要区别和联系如下&am…

【Linux】常见指令以及权限理解

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 &#x1f6f8;C专栏&#xff1a;Linux修炼内功基地 家人们更新不易&#xff0c;你们的&#x1f44d;点赞&#x1f44d;和⭐关注⭐…

Vue 中动态引入图片为什么要是 require

在vue中动态的引入图片为什么要使用require&#xff1f; 因为动态添加src被当做静态资源处理了&#xff0c;没有进行编译&#xff0c;所以要加上require&#xff0c; 我倒着都能背出来...... emmm... 乍一看好像说的很有道理啊&#xff0c;但是仔细一看&#xff0c;这句话说…

《设计模式》之单例模式

文章目录 1、定义2、动机2、类结构3、单例的表现形式4、总结4、代码实现(C) 1、定义 保证一个类仅有一个实例&#xff0c;并提供一个该实例的全局访问点。 2、动机 在软件系统中&#xff0c;经常有这样一些特殊的类&#xff0c;必须保证它们在系统中只存在一个实例&#xff…

可道云上传文件后报错: Call to undefined function shell_exec()

宝塔面板中直接一键部署的可道云&#xff0c;使用的是PHP8.0环境&#xff0c;上传文件或者点击我刚上传好的文件夹就会报错以下错误&#xff1a; 出错了! (warning!) Call to undefined function shell_exec() 系统错误 fileThumb/app.php[376] fileThumbPlugin->checkB…

UML时序图详解

上篇文章&#xff0c;介绍了UML状态图&#xff0c;并通过visio绘制一个全自动洗衣机的UML状态图实例进行讲解。 本篇&#xff0c;来继续介绍UML中的另一种图——时序图。 1 时序图简介 时序图(Sequence Diagram)&#xff0c;也叫顺序图&#xff0c;或序列图&#xff0c;是一…

基于SpringBoot的招聘信息管理系统设计与实现

前言 本次设计任务是要设计一个招聘信息管理系统&#xff0c;通过这个系统能够满足管理员&#xff0c;用户和企业的招聘信息管理功能。系统的主要功能包括首页、个人中心、用户管理、企业管理、工作类型管理、企业招聘管理、投简信息管理、面试邀请管理、求职信息管理、社区留…

银行数字化转型导师坚鹏:银行数字化转型的5大发展趋势

银行数字化转型的发展趋势主要包括以下5个方面&#xff1a; 从过去的局部数字化转型向全面数字化转型转变&#xff1a;2022年1月&#xff0c;中国银保监会发布《关于银行业保险业数字化转型的指导意见》&#xff0c;标志着中国银行业的数字化转型已经不是过去银行自己主导的局…

简单理解正向代理和反向代理

上一篇文章说到反向代理是用来做负载均衡的&#xff0c;同时我就想到了那么正向代理是不是也可以说一说&#xff0c;可能还是有很多人是弄不清他俩的区别是什么的吧&#xff1f; 那么本次文章就用借钱的例子来阐述一下什么是正向代理&#xff0c;什么是反向代理 正向代理 正…

Android系统的问题分析笔记(4) - Android设备硬件基础

问题 典型的Android手机/平板硬件架构是怎么样的&#xff1f; 1 典型Android手机/平板硬件架构图 2 基带处理器 (Baseband Processor) 市场上大多数的手机采用了相互独立的处理单元来分别处理用户界面软件和射频功能。即&#xff1a;应用处理器 (Application Processor&#…

5年积淀,Mapmost打造连接无限的数字孪生平台

数字孪生是充分利用物理模型、传感器更新、运行历史等数据&#xff0c;集成多学科、多物理量、多尺度、多概率的仿真过程&#xff0c;在虚拟空间中完成映射&#xff0c;从而反映相对应的实体装备的全生命周期过程。在“数字中国”、“实景中国”战略指导下&#xff0c;数字孪生…

【Redis】IO多路复用机制

IO多路复用的概念 IO多路复用其实一听感觉很高大上&#xff0c;但是如果细细的拆分以下&#xff0c; IO&#xff1a;网络IO&#xff0c;操作系统层面指数据在内核态和用户态之间的读写操作。 多路&#xff1a;多个客户端连接(连接就是套接字描述符&#xff0c;即Socket) 复用&…

什么是零知识证明?

零知识证明&#xff08;Zero Knowledge Proof&#xff0c;以下简称ZKP&#xff09;是一种加密学中的重要技术&#xff0c;它可以让一个人向另一个人证明某个事情是真的&#xff0c;而不需要透露这个事情的具体内容&#xff0c;即不需要泄露任何信息。ZKP 技术可以在不牺牲隐私的…

难见的oracle 9i恢复---2023年----惜分飞

时过境迁,以前恢复大量oracle 8/9版本的库,现在一套oracle 9i的库都比较稀奇了.今天恢复客户一套9.2.0.6的aix环境rac库,通过分析确认主要问题: 1. 重建控制文件&#xff0c;resetlogs库遗漏数据文件 2. 数据库启动主要报错ORA-600 2663和ORA-600 kclchkblk_4 Tue Nov 8 09:…

Python dshelper:动动鼠标,搞定数据探索!

本次分享一个Python数据探索小工具dshelper&#xff0c;适合快速查看数据基本特征、数据可视化等使用场景。 无需代码&#xff0c;自动完成数据集描述统计&#xff1b; 无需代码&#xff0c;界面点鼠标绘制多种统计图&#xff1a; 支持命令行、jupyter notebook、docker三种…

RK3588平台开发系列讲解(进程篇)Linux 进程的数据结构

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、Linux 进程的数据结构二、创建 task_struct 结构三、Linux 进程地址空间四、Linux 进程文件表沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍 Linux 如何表示进程。 一、Linux 进程的数据结构…

Java测试:OJ练习(字符串合并后返回按照先后顺序排列的不重复新字符串、合并数组并按升序排列、Arrays 类中的sort方法)

1、给定一个长度为n的字符 串&#xff0c;字符串中只包含大小写字母。 请你返回该字符串拥有那些字符。 并将它们按照出现的先后&#xff01;顺序拼接成一个新的字符串。 这是我最开始写的&#xff0c;代码有点问题&#xff1a; public String setString(String str) {char[]…