Decode360's Blog

          業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
          關于并發問題的測試
          ?
          ??? 在論壇上看到有人討論并發的這個問題,因為平時主要是處理數據倉庫,所以對并發的問題一直沒有怎么注意,記錄一下:
          ?
          ?
          --第一段:
          create or replace procedure Delete_Pno(v_Pno varchar2) is
          ? v_state varchar2(20);
          begin
          ? begin
          ??? select state into v_state from P_Table where Pno = v_Pno;
          ? exception
          ??? when no_data_found then
          ????? dbms_output.put_line('Pno:' || v_Pno || 'not exists.');
          ????? return;
          ? end;
          ? if v_state = 'N' then
          ??? delete from P_Table where Pno = v_Pno;
          ??? dbms_output.put_line('Pno:' || v_Pno || 'delete success.');
          ? else
          ??? dbms_output.put_line('Pno:' || v_Pno || 'has been checked.');
          ? end if;
          commit;
          exception
          ? when others then
          ??? rollback;
          end;
          -- 如果在 select state into v_state 之后,如果發生了狀態變化,或者單證刪除,都會發生并發性錯誤。
          --需要在select into 語句后面加上forupdate,這樣就可以鎖住該信息而防止其被修改或刪除。
          ?
          ?
          --第二段:
          create or replace procedure Delete_Pno(v_Pno varchar2) is
          ? v_state varchar2(20);
          begin
          ? delete from P_Table
          ?? where Pno = v_Pno
          ???? and state = 'N';
          ? if sql%rowcount > 0 then
          ??? dbms_output.put_line('Pno:' || v_Pno || 'delete success.');
          ? else
          ??? begin
          ????? select state into v_state from P_Table where Pno = v_Pno;
          ??? exception
          ????? when no_data_found then
          ??????? dbms_output.put_line('Pno:' || v_Pno || 'not exists.');
          ??????? return;
          ??? end;
          ??? dbms_output.put_line('Pno:' || v_Pno || 'has been checked.');
          ? end if;
          commit;
          exception
          ? when others then
          ??? rollback;
          end;
          --先刪除必然需要刪除的,然后再判斷是不存在還是無需刪除,這樣不會出現并發錯誤。
          ?
          ?
          --第三段
          create or replace procedure Delete_Pno(v_Pno varchar2) is
          ? v_state varchar2(20);
          begin
          ? delete from P_Table where Pno = v_Pno returning state into v_state;
          ? if sql%rowcount > 0 then
          ??? if v_state = 'N' then
          ????? dbms_output.put_line('Pno:' || v_Pno || 'delete success.');
          ??? else
          ????? rollback;
          ????? dbms_output.put_line('Pno:' || v_Pno || 'has been checked.');
          ????? return;
          ??? end if;
          ? else
          ??? dbms_output.put_line('Pno:' || v_Pno || 'not exists.');
          ? end if;
          commit;
          exception
          ? when others then
          ??? rollback;
          end;
          --用returning返回狀態,如果狀態是'N'則刪除,否則回滾,這樣也不會有并發的問題。
          ?
          ?
          ?
          ??? 要注意delete from P_Table where Pno = v_Pno returning state into v_state;語句屬于OUT BIND
          ??? 就好比是update ... set () = (select ...) 一樣,語句和自己的子句之間,是不會造成并發的不一致性的。
          ?
          ?
          posted on 2009-01-30 22:22 decode360 閱讀(141) 評論(0)  編輯  收藏 所屬分類: 06.PLSQL
          主站蜘蛛池模板: 满洲里市| 青阳县| 平安县| 云南省| 金堂县| 南宁市| 偏关县| 马公市| 黎城县| 武宣县| 连南| 青神县| 宁夏| 永济市| 肇庆市| 前郭尔| 昌平区| 沙雅县| 沾益县| 正阳县| 炎陵县| 中方县| 青州市| 衡阳市| 二连浩特市| 湘潭市| 佳木斯市| 灵璧县| 渭南市| 辽中县| 青龙| 吉首市| 泾阳县| 永和县| 阿坝县| 凉山| 二手房| 栖霞市| 清丰县| 永登县| 怀柔区|