Decode360's Blog

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

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            302 隨筆 :: 26 文章 :: 82 評論 :: 0 Trackbacks
          ??? 在論壇上看到有人討論并發(fā)的這個問題,因?yàn)槠綍r主要是處理數(shù)據(jù)倉庫,所以對并發(fā)的問題一直沒有怎么注意,記錄一下:
          ?
          ?
          --第一段:
          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 之后,如果發(fā)生了狀態(tài)變化,或者單證刪除,都會發(fā)生并發(fā)性錯誤。
          --需要在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;
          --先刪除必然需要刪除的,然后再判斷是不存在還是無需刪除,這樣不會出現(xiàn)并發(fā)錯誤。
          ?
          ?
          --第三段
          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返回狀態(tài),如果狀態(tài)是'N'則刪除,否則回滾,這樣也不會有并發(fā)的問題。
          ?
          ?
          ?
          ??? 要注意delete from P_Table where Pno = v_Pno returning state into v_state;語句屬于OUT BIND
          ??? 就好比是update ... set () = (select ...) 一樣,語句和自己的子句之間,是不會造成并發(fā)的不一致性的。
          ?




          -The End-

          posted on 2009-01-30 22:22 decode360-3 閱讀(166) 評論(0)  編輯  收藏 所屬分類: SQL Dev
          主站蜘蛛池模板: 桐乡市| 凤凰县| 乃东县| 资阳市| 东辽县| 静海县| 德江县| 义乌市| 泰安市| 特克斯县| 娱乐| 湖口县| 永泰县| 庄浪县| 墨脱县| 夹江县| 玛纳斯县| 精河县| 泗洪县| 辉南县| 碌曲县| 昌宁县| 南郑县| 韩城市| 屏东县| 武强县| 志丹县| 清丰县| 蒙城县| 察哈| 古田县| 祁门县| 抚宁县| 慈利县| 白河县| 临猗县| 揭阳市| 拜城县| 临漳县| 淮北市| 招远市|