關於Oracle事務的總結sql
1.什麼是事務,事務的特性是什麼?數據庫
事務的任務即是使數據庫從一種狀態變換成爲另外一種狀態,這不一樣於文件系統,它是數據庫所特用的。它的特性有四個:TOM總結爲ACID即
原子性atomicity:語句級原子性,過程級原子性,事務級原子性
一致性consistency:狀態一致,同一事務中不會有兩種狀態
隔離性isolation:事務間是互相分離的互不影響(這裏可能也有自治事務)
持久性durability:事務提交了,那麼狀態就是永久的
對於語句級原子性,過程級原子性和事務級原子性能夠查閱一下相關的信息服務器
2.Oracle中的事務語句
commit=commit work 提交
rollback=rollback work 回滾
savepoint 事務的標記點,可使一個事務在回滾到不一樣的階段
set transaction 開始一個事務
rollback to savepoint 與savepoint對應
另外對於自治事務還有一個,下面會着重說一下關於自治事務
pragma autonomous_transaction
3.關於完整性約束與事務的關係
完整性約束的模式有immediate,deferred等
語法:set constraint c_fk defereed
這對於級聯更新頗有幫助,以下面的tom在書中舉的例子:
SQL> create table p(pk int primary key);
表已建立。
SQL> create table c
2 (fk constraint c_fk
3 references p(pk)
4 deferrable
5 initially immediate
6 )
7 /
表已建立。
語句: set constraint c_fk immediate;
set constraint c_fk deferred;
SQL> set constraint c_fk immediate;
約束條件已設置。
SQL> update p set pk=3;
update p set pk=3
*
ERROR 位於第 1 行:
ORA-02292: integrity constraint (FTITEM.C_FK) violated - child record found
SQL> set constraint c_fk deferred;
約束條件已設置。
SQL> update p set pk=3;
已更新 1 行。
SQL> update c set fk=3;
已更新 1 行。
SQL> commit;
提交完成。
SQL> set constraint c_fk immediate;
約束條件已設置。
4.在事務中兩個很差的方法
tom在書上提到了兩種很差的事務使用習慣,我在工做中也是常常犯的,主要是由於對於每種數據庫的認識不到位,聽好多朋友說數據庫你只要會用了一個其它的就能夠了,通過這段時間的學習,其實咱們所說的會只是說對一SQL語句等,而並非理解,好比對於臨時表的用法,在sqlserver與oracle就不太同樣(我只用過這兩個數據庫),兩個很差的方法:
A:在循環中提交事務,這影響性能並且在快照(snapsot中也會有問題),還有一個是從新啓動(在before update on table的觸發器中會看到引用NEW,OLD會被觸發兩次)
B:使用自動提交事務,必定要手動控制事務的提交,由於自動提交會出現沒必要要的麻煩。
5.分佈式事務
在oracle中會在一個事務中控制多個數據庫,保證各個數據庫中的數據完整性,主要經過dblink,看到這我想到了本身在工做中的問題:兩臺服務器不一樣的數據庫,我一直認爲不能同時用一個事務來控制,因此在開發程序中(我用delphi開發的)我用兩個connection來進行聯接不一樣的數據庫,提交時分別提交,並且須要用狀態標識來進行事務是否正常,以前用sqlserver時也這樣操做,如今想一想笨的要死,爲何沒有用到事務的特性呢?究其緣由是,本身對於數據庫的理解差到極點了:(
在oracle中的分佈式事務的限制條件:
(1)只能在主服務器中進行事務的開始,提交,回滾等,其它服務器會根據狀態來進行判斷,即主服務器爲協調各個數據庫的狀態一致從而使其它從數據庫達到狀態一致。(應該說是站點,分站點)
(2)在dblink(數據連接)上不能作提交
(3)在dblink(數據連接)上不能作DDL操做
(4)在dblink(數據連接)不能發出savepoint等操做,即不能發出任何事務性語句
這裏補充一下關於數據庫連接的建立刪除等語法:
建立數據連接:
方法1.create database link dblink_name connect to user_name identified by
password using 'server name';
方法2.create database link dblink_name connect to user_name identified by
password
using '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = IP)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)';
刪除數據連接:
drop database link dblink_name;
使用數據連接:
select * from table@dblink_name;
6.自制事務
幾天前在pub論壇中看到一個問題是在表A上建了一個觸發呂,當對錶進行相關操做時不論成功或失敗,都想經過觸發器提交一些信息,(描述的有點不清,見諒),當時有人說用自治事務,我還尋思什麼是自治事務呢?
自治事務:是獨立於主事務的一個子事務,它的提交與回滾不影響主事務的操做(個人理解)
自治事務提供了一種用PL/SQL控制事務的新方法,能夠用於:
1 頂層匿名塊
2 本地,獨立或打包的函數和過程
3 對像類型的方法
4 數據庫觸發器
自治事務存儲過程:
SQL> create or replace procedure autonomous_insert
2 as
3 pragma autonomous_transaction;
4 begin
5 insert into t values('autonomous insert');
6 commit;
7 end;
8 /
過程已建立。
pragma是一個編譯器指令,這是一種編輯器執行某種編譯選項的方法。
非自法事務存儲過程:
SQL> create or replace procedure nonautonomous_insert
2 as
3 begin
4 insert into t values('nonautonomous insert');
5 commit;
6 end;
7 /
過程已建立。
SQL> begin
2 insert into t values('anonymous block');
3 nonautonomous_insert;
4 rollback;
5 end;
6 /
PL/SQL 過程已成功完成。
SQL> select * from t;
MSG
-------------------------
anonymous block
nonautonomous insert
由於在nonautonomous_insert中有一個commit,因此rollback基本沒有可回滾的操做。
SQL> begin
2 insert into t values('anonymous block');
3 autonomous_insert;
4 rollback;
5 end;
6 /
PL/SQL 過程已成功完成。
SQL> select * from t;
MSG
-------------------------
autonomous insert
這是由於autonomous_insert是一個自治事務,獨立於匿名塊的事務,因此rollback不會影響到它。
如何使用一個自治事務來記錄表修改的信息:建立五個audit表來記錄信息
SQL> create table audit_tab
2 (username varchar2(30) default user,
3 timestamp date default sysdate,
4 msg varchar2(4000)
5 )
6 /
表已建立。
在表emp中創建觸發器(這就能夠實現最初的那個問題)
create or replace trigger emp_audit
before update on emp
for each row
declare
pragma autonomous_transaction;
l_cnt number;
begin
select count(*) into l_cnt from dual
where exists (select null from emp
where empno=:new.empno
start with mgr=(select empno
from emp
where ename=user)
connect by prior empno=mgr);
if (l_cnt=0)
then
insert into audit_tab(msg)
values('attemp to update '||:new.empno);
commit;
raise_application_error(-20001,'access denied');
end if;
end;
總結:
1.事務應該儘量的短,即避免沒必要要的擴大事務
2.根據須要事務足夠大
3.決定事務大小的關鍵是數據完整性。
4.能決定事務大小的惟一約束就是控制系統的業務規則,不是undo,不是鎖等。oracle