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 閱讀(166) 評論(0)  編輯  收藏 所屬分類: SQL Dev
          主站蜘蛛池模板: 延吉市| 沙雅县| 开化县| 南通市| 裕民县| 垫江县| 靖远县| 米林县| 上犹县| 河池市| 景谷| 虞城县| 邻水| 山阳县| 昌乐县| 大悟县| 重庆市| 溆浦县| 灵川县| 阳江市| 鲜城| 舟曲县| 安徽省| 株洲市| 通城县| 蛟河市| 龙泉市| 原平市| 乌什县| 五指山市| 萝北县| 霍城县| 武冈市| 斗六市| 曲松县| 贵定县| 金寨县| 射洪县| 泰安市| 永寿县| 财经|