Decode360's Blog

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

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評論 :: 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 ...) 一樣,語句和自己的子句之間,是不會造成并發的不一致性的。
          ?




          -The End-

          posted on 2009-01-30 22:22 decode360-3 閱讀(175) 評論(0)  編輯  收藏 所屬分類: SQL Dev
          主站蜘蛛池模板: 丰镇市| 禹州市| 仙游县| 原阳县| 平度市| 噶尔县| 炉霍县| 昌图县| 文昌市| 德钦县| 灵丘县| 嵊泗县| 竹溪县| 长寿区| 密云县| 陇南市| 灵丘县| 东乡| 本溪市| 介休市| 特克斯县| 健康| 若尔盖县| 宁陵县| 承德市| 犍为县| 菏泽市| 墨江| 容城县| 曲靖市| 丹东市| 从化市| 科技| 定远县| 乌鲁木齐县| 三亚市| 景泰县| 长葛市| 社旗县| 大埔区| 民丰县|