问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何解决Oracle Rac数据不同步问题

发布网友 发布时间:2022-04-29 22:07

我来回答

2个回答

懂视网 时间:2022-04-30 02:28

begin declare i int;tmpcount int;tbname varchar2(50);strsql varchar2(1000); begin i:=0; while i<10 loop begin tbname := ‘tb_employeeinfo‘||to_char(i); i := i+1; select count(1) into tmpcount from user_tables where table_name = Upper(tbname); if tmpcount>0 then begin execute immediate ‘drop table ‘||tbname; commit; end; end if; strsql := ‘create table ‘||tbname|| ‘( employeeno varchar2(10) not null, -- employee number employeeage int not null -- employee age )‘; execute immediate strsql; strsql := ‘begin execute immediate ‘‘drop index idx1_‘||tbname || ‘ ‘‘‘ || ‘;exception when others then null; end;‘; execute immediate strsql; execute immediate ‘create unique index idx1_‘||tbname||‘ on ‘||tbname||‘(employeeno)‘; end; end loop; end; end; /

插入数据的存储过程语句如下:

begin
 declare v_i int;v_procname varchar(50);v_employeeinfotbl varchar(50);strsql varchar(4000);
begin
 v_i := 0;
 while v_i < 10 loop
 v_procname := ‘pr_insertdata‘||substr(to_char(v_i),1,1);
 v_employeeinfotbl := ‘tb_employeeinfo‘||substr(to_char(v_i),1,1);

 v_i := v_i + 1;
 strsql := ‘create or replace procedure ‘||v_procname||‘(
  v_employeeno in varchar2,
  v_employeeage in int,
  v_retcode out int -- 0_success, 1,2_fail
 )
 as
  v_employeecnt int;

 begin
  v_retcode := 0;

  select count(*) into v_employeecnt from ‘||v_employeeinfotbl||‘ where employeeno = v_employeeno;
  if v_employeecnt > 0 then -- the employeeno is already in DB
  begin
  v_retcode := 1;
  return;
  end;
  else    -- the employeeno is not in DB
  begin
  insert into ‘||v_employeeinfotbl||‘(employeeno, employeeage) values(v_employeeno, v_employeeage);
  end;
  end if;
 exception when others then
  begin
  rollback;
  v_retcode := 2;  
  return;
  end;
 end;‘;
 execute immediate strsql;
 end loop;
 end;
end;
/

我们在PL/SQL Developer软件上执行了以上SQL语句(注意:先建表,后建存储过程)之后,利用以下SQL语句向tb_employeeinfo6表中插入数据:

set serveroutput on
declare v_retcode int;
begin
pr_insertdata6(‘123456‘, 25, v_retcode);
dbms_output.put_line( v_retcode);
end;
/

执行“select * from tb_employeeinfo6;”语句查询数据,结果如下:

SQL> select * from tb_employeeinfo6;
EMPLOYEENO EMPLOYEEAGE
---------------------------
123456  25

可见,数据插入成功。

接着,我们利用以下命令行从Linux系统上登录到ORACLE数据库中(注意:username是指数据库用户名,password是指数据库密码,databaseservername是指数据库服务名):

sqlplus /nolog
connect username/password@databaseservername

然后执行如下查询语句:

select * from tb_employeeinfo6;

发现返回的值为空,即该数据表中没有数据。
真是奇怪了,为什么同样的查询语句,两边的执行结果不一致呢?
我们回过头来详细阅读了建表和建存储过程的代码,没看出有明显的问题。我们将该问题告诉了一位工作多年的老员工,请他来帮我们分析问题的原因所在。他详细看了我们的SQL语句之后,便指出存储过程的代码有点问题,在向表中插入数据之后忘记提交了。也就是说,存储过程中的“insert…”语句之后应该加上“commit;”。
难道就是这个“commit;”语句惹的祸吗?

三、问题原因
我们将存储过程的代码修改为如下:

begin
 declare v_i int;v_procname varchar(50);v_employeeinfotbl varchar(50);strsql varchar(4000);
begin
 v_i := 0;
 while v_i < 10 loop
 v_procname := ‘pr_insertdata‘||substr(to_char(v_i),1,1);
 v_employeeinfotbl := ‘tb_employeeinfo‘||substr(to_char(v_i),1,1);

 v_i := v_i + 1;
 strsql := ‘create or replace procedure ‘||v_procname||‘(
  v_employeeno in varchar2,
  v_employeeage in int,
  v_retcode out int -- 0_success, 1,2_fail
 )
 as
  v_employeecnt int;

 begin
  v_retcode := 0;

  select count(*) into v_employeecnt from ‘||v_employeeinfotbl||‘ where employeeno = v_employeeno;
  if v_employeecnt > 0 then -- the employeeno is already in DB
  begin
  v_retcode := 1;
  return;
  end;
  else    -- the employeeno is not in DB
  begin
  insert into ‘||v_employeeinfotbl||‘(employeeno, employeeage) values(v_employeeno, v_employeeage);
  commit;
  end;
  end if;
 exception when others then
  begin
  rollback;
  v_retcode := 2;  
  return;
  end;
 end;‘;
 execute immediate strsql;
 end loop;
 end;
end;
/

接着,我们在PL/SQL Developer软件上执行了以上SQL语句,并利用以下SQL语句向tb_employeeinfo9表中插入数据:

set serveroutput on
declare v_retcode int;
begin
pr_insertdata9(‘123469‘, 25, v_retcode);
dbms_output.put_line( v_retcode);
end;
/

同样在该软件上执行“select * from tb_ employeeinfo9;”语句查询数据,结果如下:

SQL> select * from tb_employeeinfo9;
EMPLOYEENO EMPLOYEEAGE
--------------------------
123469  25

然后在Linux系统上执行“select * from tb_employeeinfo9;”语句,结果如下:

SQL> select * from tb_employeeinfo9;
EMPLOYEENO EMPLOYEEAGE
------------------------
123469 25

可见,数据被成功插入到员工信息表中。

四、总结
对于本次因为“commit;”而引发的问题,我们的总结如下:
第一,在动手编写代码之前,一定要对语法规则了然于心,不要让一个小小的问题引起整个软件功能的异常。
第二,在软件开发中,经验十分的重要。一个新人花几个小时不能解决的问题,一个老手可能几分钟就搞定了。因此,在遇到自己不能解决的问题的时候,我们一定要勤于开口,多多向有经验的老员工请教。


本人微信公众号:zhouzxi,请扫描以下二维码:
技术分享

一起ORACLE数据库中数据查询结果不一致问题的排查过程

标签:

热心网友 时间:2022-04-29 23:36

 现在有这样的环境:
  一台web Server,一个是纯JAVA APP 程序
  数据库两台做成RAC的形式. web Server与APP 程序都通过oci(rac)的方式连接数据库.
  出了这样的怪问题,webServer更新或是插图入一条数据,后面紧跟着的在APP中就查询不到,等到用工具查询就没有问题.
  初步怀疑
  1. RAC方式下面的数据库两个instance的同步没做好?
  查询相关资料发现在与MAX_COMMIT_PROPAGATION_DELAY有关.
  最大提交传播时延(MAX_COMMIT_PROPAGATION_DELAY,简称MCPD),在ORACLE RAC(或OPS)环境中才使用,表示在RAC系统中,一个instance系统提交产生的最新系统改变码(SCN),能够以多快的速度反应到另一个instance中.
  举例说明,RAC系统,有A,B两个实例(instance),A、B本地系统改变码为SCN1,A更新数据DATA1提交, LGWR操作完成后,A本地系统改变码为SCN2,经过不大于MAX_COMMIT_PROPAGATION_DELAY时间后,B系统本地改变码才变为SCN2.
  Global Cache ServICes 将刷新RAC中的SCN.不管SCN是否及时刷新,后续的数据查询都不会因此产生数据库错误.但,在此时间内,有可能查询结果不是最新数据,产生读一致性(read consistency)问题.
  RAC环境中的所有实例,此参数值必须相同.
  ORACLE8i后,建议常用的两个值是0和700(默认),其他数值皆不建议.其实,这两个数值就代表了RAC环境中,两种SCN 产生机制:
  Lamport Scheme和 Broadcast on Commit scheme.
  设置为默认值700,表示采用Lamport Scheme,SCN改变不会完全同步,同步将在 7秒钟内完成,而不是总等待7秒钟后才完成.如果系统比较空闲,同步可能在0.5秒(甚至更短时间)内完成;不管系统多繁忙,同步时间也不可能超过7秒.不难理解,采用此模式,整个RAC系统的运行效率较高.
  设置为0,表示采用Broadcast on Commit scheme,SCN改变完全同步.每当commit时(即LGWR 写redo log时):
  - LGWR发送消息更新全局SCN(global SCN),
  - LGWR 发送消息给每个活动的实例更新其本地SCN(LOCal SCN).
  有资料说,只要MCPD < 700,系统将采用Broadcast on Commit scheme.
  Lamport Scheme能够适应绝大部分应用的要求,只有个别实时性特别高的业务,才需要Broadcast on Commit scheme.通过分析,不难理解,Broadcast on Commit scheme将需要更多的系统资源.
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
梦字最佳名字组合 男宝宝取名梦什么名字 带梦的男孩名字大全集 带梦字的男孩名字有哪些? 联想fn是哪个键 联想电脑怎么设置fn 国庆煲剧指南|板鸭小姐姐Netflix私藏之追剧清单 韩剧tv停更后,大家哪里去看这些资源了呢? 韩剧tv在哪给剧集打分 剧集打分操作教程分享 使用翻转课堂的用户是 老师,您好!我是新手,想买佳能700D单机配腾龙18-200的镜头,听说18... 有没有办法在怀孕的时候检查到孩子的父亲 华为nova2s NTFS和FAT32 SD卡格式的区别? 现在是不是怀孕期间就可以验胎儿亲子鉴定的知道亲生父亲是谁了?在中山有吗? 破身为奴小说txt全集免费下载 华为Nova2s 6+64 还可以加256G内存卡吗? 求一小说名,女主病了朋友送给她一个家奴伺候,是个总裁,忘记叫什么了 怀孕了不知道孩子父亲是谁,惠州可以验DNA亲子鉴定吗? 怀孕多久能验出孩子父亲是谁 《奴为孰来娇》扣弦为歌小说txt全集免费下载 怀孕多久验DNA才能验出孩子的父亲 我在南昌不知道怀孕的胎儿岁才是亲生父亲请问可以验出来吗?我怀孕2个月了 我昨晚戴着镣铐睡觉,早上就是感觉手酸。刺激 华为nova2s支持A2存储卡吗? 禁奴小说txt全集免费下载 一生为奴小说txt全集免费下载 求小说《军奴左三知》的完整版全文+番外! 求小说《军奴左三知》的完整版全文+番外 父母给我戴上脚镣我该怎么办? 官庄蜘蛛洞的小故事 为什么有的女生是格子控 为什么喜欢穿格子衬衫呢 《蜘蛛开店》续写100字 职业药师考试怎么报名 请问华为nova2s能用多大的内存卡? 抖音上小黄脸捂嘴呆眼表情是什么意思? 谁能给我发一下《警察为奴》这篇小说啊 怀孕五个月了,能查到孩子父亲是谁吗 药学专业如何报考? 2015辽宁执业药师报名条件都有什么?报名网址在哪? &quot;大众媒介挣脱了铁的枷锁,又戴上了银的镣铐&quot;出自哪里?哪本书?作者是谁? 《小小乖奴隶》凌舞宸轩小说txt全集免费下载 2015辽宁执业药师报名条件?报名时间是什么时候? 2019年辽宁执业药师考试报名什么时间开始? wps“办公空间”中,有个“输出为图片”,,,请问怎么设置输出图片的大小和分辨率??? 我明天就要听写了,可是我没把握。有没有什么好的方法。(应对英语听写 ) 品社妈妈陪朋友聊天,我要听写英语单词 怎么办 辽宁执业药师缴费通道关闭了吗? 救急!!!很小的照片为什么复制到WPS 表格里就变得很大 怎么缩小? 怎么样背单词最快?我们要听写 各位大神,明天我要听写100个英语单词但是我今天只记住了20个,谁有好的记忆法。急急急 明天我要听写100个英语单词但是我今天只记住了20个,谁有好的记忆法.急 123单元,怎么听写听写我要听写?