Oracle数据库优势说明.docx
《Oracle数据库优势说明.docx》由会员分享,可在线阅读,更多相关《Oracle数据库优势说明.docx(32页珍藏版)》请在冰豆网上搜索。
Oracle数据库优势说明
Oracle数据库优势说明
神州数码融信软件有限公司
尊敬的德阳银行:
我们的核心业务系统解决方案是以“客户为中心、以产品为导向”,致力于构建先进银行IT架构,覆盖“柜面、企业服务总线、核心系统、数据平台”等,方案结合了国际先进理念,能够满足国内商业银行的业务需求。
神州数码的核心业务系统解决方案在国内有10个成功实施案例。
神州数码向贵行业务和技术专家详细介绍了神州数码核心业务系统的系统功能、系统架构和实施理念。
针对德阳银行的担心和疑虑,我们非常理解德阳银行的这种忧虑,为确保双方的有效沟通,我们的技术人员对相关问题进行整理,请查收。
如果有问题,请不吝赐教。
颂颂商祺!
神州数码融信软件有限公司
目录
一、核心系统存储过程概述4
二、核心系统存储过程的实现提高了性能5
1、处理模式对比-单笔交易情况5
2、处理模式对比-大批量并发交易情况6
三、核心存储过程复杂业务的处理过程(卡折关联)8
1、代码说明:
8
1)定义存储过程名字和变量8
2)存储过程数据变量的初始化和实例化9
3)业务逻辑处理10
4)过程结束处理15
5)卡折关联实现过程总结:
15
四、Oracle数据库日志处理框架机制17
1、设计原则17
2、总体架构17
1)功能架构17
2)技术架构18
3、Forexample20
五、Oracle开发调试首选工具—Toad21
1、SchemaBroswer21
2、SQLEditor22
3、ProcedureEditor23
4、PL/SQLDebugger24
5、CodeProfiling25
六、Oracle数据库面向对象技术27
1、面向对象说明27
2、Forexample29
1)对象继承29
2)对象方法构造30
3)对象方法可以采用不同语言构造(PL/SQL或C或JAVA)31
一、核心系统存储过程概述
数据库技术的发展到今天,已经不再只是存储、管理数据的载体,其发展趋势越来越广,对应用的支撑越来越强。
神州数码的核心业务系统Ensemble完全采用Orcale数据库技术,充分利用数据库的优势,主要有以下几个方面的考虑:
1、Orcale数据库是目前数据库业界(尤其是在金融行业),应用最为广泛、安全性最高、技术最为成熟的数据库系统。
根据Oracle的数据表明,目前Orcale数据已经成为数据库市场最为领先的数据库系统。
2、以PL/SQL为代表的数据库存储过程本质上已经是一种介于结构化和面向对象之间的高级语言了,因此在代码的编写、编译上没有过多的本质不同。
在运行机制上通过对多条SQL操作的集约化处理,通过使用数据库内部的优化机制和执行策略,更能适应需要频繁访问数据库表的大型应用系统的要求。
3、Ensemble充分利用了Oracele数据库底层的技术,确保核心业务系统能够高性能运行,避免了传统的外部程序频繁调用数据库导致的性能问题。
4、Oracle技术在支持Java技术、SOA架构、面向对象等技术方面表现非常优秀和卓越。
5、数据库单独部署、RAC技术,消息队列机制、日志管理机制、批处理机制等非常完善,为银行核心业务系统的核心处理机制提供了完整的支持。
6、在便于备份管理、数据及应用恢复等方面,数据库优势越来越明显。
数据库提供的灾难备份和容灾处理技术,也催生行业应用越来越集中在数据库端。
二、核心系统存储过程的实现提高了性能
核心业务系统用数据库存储过程实现,大大提高了系统的性能,我们以单笔交易处理情况和大批量并发交易情况为例说明一下用程序实现和用存储过程实现的区别和优劣:
1、处理模式对比-单笔交易情况
对比如下:
1.采用应用程序处理业务逻辑即使在一次业务请求的情况下也会涉及到多次数据库调用。
缺点在:
a)将有大量时间占用数据库连接(等待下次调用或等待数据库返回),造成连接资源稀缺
b)多次数据库请求和返回造成多次网络开销,效率低。
c)需要在第一次调用前开启事务和在最后一次调用后关闭事务,事务管理复杂,忘记事务管理是编程过程中经常出现的错误,最后导致事务不一致。
2.采用MBSD框架下的存储过程处理业务逻辑,保证一次业务请求对应一次数据库请求,优点在:
a)一次业务请求对应一次数据库请求,极大减少应用和数据库之间的通讯,减少网络开销,效率高。
b)一次数据库请求无需占用数据库连接,提高数据库连接的使用效率
c)存储过程自身即带有事务管理支持,无需复杂事务管理,编程方便。
d)MBSD框架更在上述优点之上增加异步消息机制,更加降低对数据库连接的占用,同时提供了多队列的消息接收处理为下面将要讲到的大批量并发请求提供高性能支持。
2、处理模式对比-大批量并发交易情况
对比如下:
1.采用应用程序处理业务逻辑往往涉及多层次的性能问题,缺点如下:
a)大并发下出了需要解决应用程序级别的并发性能问题,还需要解决应用程序访问数据库的性能问题。
b)大并发下,应用程序对数据库的访问次数是N*N的级别,数据库访问量急剧增加,网络开销更加增大
c)大并发下,由于每笔交易都要占用一段时间数据库连接,在数据库连接这个资源有限的情况下,没有得到该资源的交易只有等待,增加交易处理时间
d)大并发下,即使在单独一笔交易已经解决的事务问题,很可能在
并发情况下出现脏读,脏写问题(比方:
两个交易同时查询了同一数据,修改后在存入数据库)。
为了避免脏读,脏写需要额外的程序开发保证资源获取和资源锁管理,增加开发量也降低性能
2.采用MBSD框架下的存储过程处理业务逻辑处理大并发交易,优点如下:
a)大并发下,应用程序对数据库的访问次数是N的级别,因为每次业务请求只访问一次数据库,是线性增加,同时网络开销小。
b)大并发下,通过MBSD框架异步消息机制,每笔请求无需占用数据库连接,使得更多的请求能够用上数据库连接。
并发越大,体现的效能越高。
c)由于存储过程自身拥有事务管理,并可以更细粒度管理资源锁,可以有效地避免脏读、脏写问题,提高效率,基本无需额外开发工作量。
三、核心存储过程复杂业务的处理过程(卡
折关联)
存储过程编写的核心处理逻辑本质上和采用C/Java等高级语言编写的程序没有不同,这里举一个例子进行说明。
1
采用的语言
PL/SQL
2
数据库
Oracle
3
处理逻辑
卡折关联。
该过程用于将一个具有存折的无卡账户和一个卡户进行关联,形成一卡通下的存折户。
该处理逻辑负责最终的数据提交处理,例如授权检查等等校验处理另有专门的存储过程负责。
1、代码说明:
1)定义存储过程名字和变量
/******************************************************************************
FunctionDescription:
卡折关联
Modificationlog:
DateAuthorDescription
--------------------------------------------------------------------
xxxx/xx/xxxxx.xxxxx
******************************************************************************/
PROCEDUREcard_bankbook_associate(
p_inputINSYS.ANYDATA,
p_outINOUTSYS.ANYDATA,
p_statusOUTVARCHAR2
)
IS
v_inputrb_passbook_i_t;
v_outrb_passbook_o_t;
v_ret_codeVARCHAR2(20);
v_sys_head_omsg_sys_header_o_t;
v_sys_head_imsg_sys_header_i_t;
v_internal_keyrb_acct.internal_key%TYPE;
v_main_tbl_keyrb_acct.main_tbl_key%TYPE;
v_doc_typerb_aio_acct.doc_type%TYPE;
v_statusrb_voucher_rd_dtl.status%TYPE;
v_dateDATE;
v_new_statusrb_voucher_rd_dtl.status%TYPE;
v_tran_descrb_vou_chq_change_hist.tran_desc%TYPE;
这里card_bankbook_associate代表了进行卡折关联的处理逻辑,它具有一个单纯的输入对象p_input用于在调用过程时将请求的输入参数传入过程,一个同时作为输入和输出对象p_out用于将存储过程处理过后的数据输出给调用者,同时返回一个用于表示过程执行成功与否的输出值p_status。
本质上,成为存储过程参数的数据等同于C/C++指针所指向的存储空间或者是C++/Java所描述对象。
在命名结束后,也需要针对过程内部所使用的变量进行申明,以便执行时分配相应的内存区以做数据交换,在PL/SQL的语法描述里就是IS以下的部分。
这些变量,可以是具体的数据库类型,也可以引申于用户自定义的数据对象,包括表、视图等等,也可以是结构、数组等复合类型。
从这里可以看出,在内存使用方式上,以PL/SQL为代表的高级关系数据库存储过程开发语言所体现出来的数据定义已经和高级语言没有本质上的不同了。
2)存储过程数据变量的初始化和实例化
BEGIN
cbsd_log.DEBUG('CARD_BANKBOOK_ASSOCIATEstart.....');
/*获取输入数据*/
v_ret_code:
=p_input.getobject(v_input);
v_ret_code:
=p_out.getobject(v_out);
v_sys_head_o:
=v_out.getsyshead;
v_sys_head_i:
=v_input.getsyshead;
p_status:
='000000';
v_date:
=rb_pwpb_maint.get_sysdate;
存储过程用于描述程序体的部分通常使用BEGIN......END进行划界,等同于高级语言“{”、“}”等分界符的使用。
由其包含的内容为程序具体的处理逻辑。
上面出现的cbsd_log.DEBUG是由Sm@rtEnsemble核心系统提供的标准日志函数,它所使用的日志处理方式是通过将代码中程序员事先编写进代码中的日志信息,输送到队列当中,然后会有专们的日志处理线程将这些不同等级的日志信息选择性的输出到日志文件当中以供技术人员备查。
这样做的好处是通过异步的方式将日志的记录和实际业务逻辑处理分离开,让日志的记录不影响业务的处理,减少系统IO相应,提高系统性能。
紧接着日志输出的是相关变量的初始化操作,可以看出,在PL/SQL当中,既有直接赋值的变量初始化方式,也有采用构造函数(例如p_input.getobject)这样的方式进行对象实例化的数据初始化方式。
目前的主流数据库存储过程都提供了加、减、乘、除、模、位移等运算符的操作,同时还提供了大量的工具包(以函数或对象方式使用)以支持复杂的数据运算和处理。
3)业务逻辑处理
IF(v_input.option_kw<>'01'ANDv_input.option_kw<>'02')
THEN--无效的操作标识
raise_application_error(-20000,'340237');
ENDIF;
--卡折关联
IF(v_input.option_kw='01')
THEN
v_new_status:
='ACT';
v_tran_desc:
='卡折关联';
/*获得AIO账户的内部标识*/
BEGIN
SELECTmain_tbl_key,doc_type
INTOv_main_tbl_key,v_doc_type
FROMrb_aio_acct
WHEREaio_acct_no=v_input.base_acct_no;
EXCEPTION
WHENNO_DATA_FOUND
THEN--无效帐户
raise_application_error(-20000,'300395');
END;
IFv_doc_typeISNOTNULL
THEN
raise_application_error(-20000,'100054');
ENDIF;
--检查凭证信息(即存单信息)是否已经由此柜员领用
BEGIN
SELECTstatus
INTOv_status
FROMrb_voucher_rd_dtlrv
WHERErv.voucher_no=v_input.voucher_no
ANDNVL(rv.prefix,'~')=NVL(v_input.prefix,'~')
ANDrv.doc_type=v_input.doc_type
ANDrv.officer_id=v_sys_head_i.user_id;
EXCEPTION
WHENNO_DATA_FOUND
THEN
raise_application_error(-20000,'340015');--凭证不存在
END;
IFv_status='NEW'--入库
THEN--此柜员没有领用此存单
raise_application_error(-20000,'306001');
ELSIFv_status='ACT'--出售
THEN
raise_application_error(-20000,'309906');
ELSIFv_status='CAN'---作废
THEN
raise_application_error(-20000,'303071');
ELSIFv_status='USE'---使用
THEN
raise_application_error(-20000,'309906');
ELSIFv_status='VER'--口头挂失
THEN
raise_application_error(-20000,'303074');
ELSIFv_status='RET'---退回
THEN
raise_application_error(-20000,'309906');
ELSIFv_status='LCB'--丢失
THEN
raise_application_error(-20000,'303074');
ELSIFv_status='LCC'--挂失
THEN
raise_application_error(-20000,'303074');
ELSIFv_status='PEN'---待复核
THEN
raise_application_error(-20000,'303071');
ELSIFv_status='DES'--销毁
THEN
raise_application_error(-20000,'309905');
ELSIFv_status!
='ASS'
THEN
raise_application_error(-20000,'309906');
ENDIF;
/*只有状态是ASS:
领用,才能继续*/
--更新rb_voucher_rd_dtl表中凭证属性修改为已使用
UPDATErb_voucher_rd_dtlrv
SETinternal_key=v_main_tbl_key,
rv.status='ACT',
rv.new_status='ACT',
rv.old_status=status
WHERErv.voucher_no=v_input.voucher_no
ANDNVL(rv.prefix,'~')=NVL(v_input.prefix,'~')
ANDrv.doc_type=v_input.doc_type
ANDrv.officer_id=v_sys_head_i.user_id;
--关联账户与存折DOC_TYPE/PREFIX/PB_NO
UPDATErb_aio_acct
SETdoc_type=v_input.doc_type,
prefix=v_input.prefix,
pb_no=v_input.voucher_no
WHEREaio_acct_no=v_input.base_acct_no;
--修改RB_ACCT_ATTACH表
UPDATErb_acct_attach
SETdoc_type=v_input.doc_type,
prefix=v_input.prefix,
pb_no=v_input.voucher_no,
withdrawal_type='P',
pb_flag='Y'
WHEREinternal_keyIN(
SELECTinternal_key
FROMrb_acct
WHEREmain_tbl_key=v_main_tbl_key
ANDNVL(deposit_type,'~')<>'T');
--修改RB_TRAN_HIST表
UPDATErb_tran_hist
SETpbk_upd_flag='Y'
WHEREinternal_keyIN(
SELECTinternal_key
FROMrb_acct
WHEREmain_tbl_key=v_main_tbl_key
ANDNVL(deposit_type,'~')<>'T');
--修改存折标识
UPDATErb_acct
SETstmt_pbk='P'
WHEREmain_tbl_key=v_main_tbl_key
ANDNVL(deposit_type,'~')<>'T';
UPDATErb_base_acct
SETwithdrawal_type='P'
WHEREbase_acct_no=v_input.base_acct_no;
--插入密码表
IF(v_input.PASSWORDISNULL)
THEN
raise_application_error(-20000,'300638');--密码不能为空
ENDIF;
INSERTINTOrb_password
(acct_no,main_tbl_key,wd_pwd,
wd_pwd_status
)
VALUES(v_input.base_acct_no,v_main_tbl_key,v_input.PASSWORD,
'A'
);
INSERTINTOrb_password_hist
(password_old,password_new,change_type,change_date,
time_stamp,change_reason,officer_id,
acct_no
)
VALUES(NULL,v_input.PASSWORD,'CRE',fm_util.v_run_date,
v_date,'CREATION',v_sys_head_i.user_id,
v_input.base_acct_no
);
ENDIF;
--取消关联
IF(v_input.option_kw='02')
THEN
v_new_status:
='CAN';
v_tran_desc:
='卡折关联取消';
BEGIN
SELECTstatus
INTOv_status
FROMrb_voucher_rd_dtlrv
WHERErv.voucher_no=v_input.voucher_no
ANDNVL(rv.prefix,'~')=NVL(v_input.prefix,'~')
ANDrv.doc_type=v_input.doc_type;
EXCEPTION
WHENNO_DATA_FOUND
THEN
raise_application_error(-20000,'340015');--凭证不存在
END;
BEGIN
SELECTmain_tbl_key,doc_type
INTOv_main_tbl_key,v_doc_type
FROMrb_aio_acct
WHEREaio_acct_no=v_input.base_acct_no
ANDpb_no=v_input.voucher_no
ANDNVL(prefix,'~')=NVL(v_input.prefix,'~')
ANDdoc_type=v_input.doc_type;
EXCEPTION
WHENNO_DATA_FOUND
THEN--关联不存在
raise_application_error(-20000,'100107');
END;
UPDATErb_voucher_rd_dtlrv
SETrv.internal_key=NULL,
rv.old_status=rv.status,
rv.status='CAN',
rv.new_status='CAN'
WHERErv.voucher_no=v_input.voucher_no
ANDNVL(rv.prefix,'~')=NVL(v_input.prefix,'~')
ANDrv.doc_type=v_input.doc_type;
UPDATErb_aio_acct
SETdoc_type=NULL,
prefix=NULL,
pb_no=NULL
WHEREaio_acct_no=v_input.base_acct_no;
UPDATErb_acct_attach
SETdoc_t