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
          主站蜘蛛池模板: 繁峙县| 皋兰县| 汉川市| 兴和县| 南宁市| 博野县| 临夏市| 且末县| 梓潼县| 黄大仙区| 修武县| 桂东县| 错那县| 高尔夫| 梨树县| 镇赉县| 司法| 察雅县| 宜君县| 惠来县| 吉安市| 元谋县| 武功县| 武穴市| 民和| 廉江市| 安丘市| 和田县| 全州县| 车险| 永安市| 平罗县| 白玉县| 黑龙江省| 雅江县| 凤山市| 乌海市| 正阳县| 罗平县| 德阳市| 区。|