Oracle事务

Oracle事务的ACID特性

原子性Atomicity:事务中的所有动作要么都发生,要么都不发生。
一致性Consistency:事务将数据库从一种状态转变为下一种一致状态。
隔离性Isolation:一个事务的影响在该事务提交前对其他事务时不可见的。
持久性Durability:事务一旦提交,其影响就是永久性的。

事务控制语句

事务隐式开始

事务必须显示结束(Commit、Rollback)

Commit 会结束事务,并使得已做的修改持久的保存在数据库中
Rollback 会结束事务,并撤销这个事务所做的修改。撤销动作需要读取回滚段中的信息,并把数据恢复到事务开始之前的状态
Savepoint 创建标记点(marked point),一个事务可以有多个标记点
Rollback To<Savepoint> 把事务回滚到指定的标记点,但是不回滚此标记点之前的工作。
Set transaction 允许设置不同的事务属性,如事务的隔离级别以及事务时只读的还是可读可写的。

原子性

语句级原子性

SQL> create table t2(cnt int);

Table created.

SQL> insert into t2 values(0);

1 row created.

SQL> create table t(x int check(x>0));

Table created.

SQL> create or replace trigger t_trigger
  2  before insert or delete on t for each row
  3  begin
  4    if ( inserting ) then
  5        update t2 set cnt=cnt+1;
  6    else
  7        update t2 set cnt=cnt-1;
  8    end if;
  9    dbms_output.put_line(‘I fired and updated‘||sql%rowcount||‘rows‘);
10  end;
11  /

SQL> set serveroutput on
SQL> select * from t2;

CNT
----------
     0

SQL> select * from t;

no rows selected

SQL> insert into t values(1);
I fired and updated1rows

1 row created.

SQL> insert into t values(-1);
I fired and updated1rows
insert into t values(-1)
*
ERROR at line 1:
ORA-02290: check constraint (EODA.SYS_C007120) violated

SQL> select * from t2;

CNT
----------
     1

过程级原子性
Oracle把PL/SQL匿名块也当做是语句

SQL> create or replace procedure p
  2  as
  3  begin
  4     insert into t values(1);
  5     insert into t values(-1);
  6  end;
  7  /

Procedure created.

SQL> delete from t;

0 rows deleted.

SQL> update t2 set cnt=0;

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from t;

no rows selected

SQL> select * from t2;

CNT
----------
     0

SQL> begin
  2  p;
  3  end;
  4  /
begin
*
ERROR at line 1:
ORA-02290: check constraint (EODA.SYS_C007120) violated
ORA-06512: at "EODA.P", line 5
ORA-06512: at line 2

SQL> set serveroutput on
SQL> /
I fired and updated1rows
I fired and updated1rows
begin
*
ERROR at line 1:
ORA-02290: check constraint (EODA.SYS_C007120) violated
ORA-06512: at "EODA.P", line 5
ORA-06512: at line 2

SQL> select * from t;

no rows selected

SQL> select * from t2;

CNT
----------
     0

事务级原子性
DDL与原子性

持久性

COMMIT的WRITE扩展
      COMMIT WRITE WAIT (默认)必须等待redo写到磁盘才返回消息给客户端
      COMMIT WRITE NOWAIT 异步提交,redo条目还没写入磁盘就返回消息给客户端
非分布式PL/SQL代码块中的COMMIT
      在后台以异步的方式执行
      即commit=commit write nowait

完整性约束和事务

Immediate约束  
     整个SQL语句得到处理后立即检查

SQL> create table t(x int unique);

Table created.

SQL> insert into t values(1);

1 row created.

SQL> insert into t values(2);

1 row created.

SQL> commit;

Commit complete.

SQL> update t set x=x-1;

2 rows updated.

Deferrable约束和级联更新

SQL> create table parent
  2  (pk int primary key)
  3  /

Table created.

SQL> create table child
  2  (fk constraint child_fk_parent
  3      references parent(pk)
  4      deferrable
  5      initially immediate
  6  )
  7  /

Table created.

SQL> insert into parent values(1);

1 row created.

SQL> insert into child values(1);

1 row created.

SQL> update parent set pk=2;
update parent set pk=2
*
ERROR at line 1:
ORA-02292: integrity constraint (EODA.CHILD_FK_PARENT) violated - child record found

由于约束是IMMEDIATE模式,update失败,换为deferred模式
SQL> set constraint child_fk_parent deferred;

Constraint set.

SQL> update parent set pk=2;

1 row updated.

SQL> set constraint child_fk_parent immediate;
set constraint child_fk_parent immediate
*
ERROR at line 1:
ORA-02291: integrity constraint (EODA.CHILD_FK_PARENT) violated - parent key not found

SQL> update child set fk=2;

1 row updated.

SQL> set constraint child_fk_parent immediate;

Constraint set.

SQL> commit;

Commit complete.

不好的事务习惯

在循环中提交
   1.性能影响


SQL> create table t as select * from all_objects;

Table created.

SQL> exec dbms_stats.gather_table_stats(user,‘T‘);

PL/SQL procedure successfully completed.

SQL> variable n number
SQL> exec :n:=dbms_utility.get_cpu_time;

PL/SQL procedure successfully completed.

SQL> update t set object_name=lower(object_name);

17977 rows updated.

SQL> exec dbms_output.put_line((dbms_utility.get_cpu_time-:n)||‘ cpu hsecs...‘);
25 cpu hsecs...

PL/SQL procedure successfully completed.

SQL> exec :n:=dbms_utility.get_cpu_time;

PL/SQL procedure successfully completed.

BEGIN
   FOR x IN (SELECT ROWID rid, object_name, ROWNUM r FROM t)
   LOOP
      UPDATE t
         SET object_name = LOWER (x.object_name)
       WHERE ROWID = x.rid;

IF (MOD (x.r, 100) = 0)
      THEN
         COMMIT;
      END IF;
   END LOOP;

COMMIT;
END;

/

PL/SQL procedure successfully completed.

SQL> exec dbms_output.put_line((dbms_utility.get_cpu_time-:n)||‘ cpu hsecs...‘);
108 cpu hsecs...

PL/SQL procedure successfully completed.


SQL> exec :n:=dbms_utility.get_cpu_time;

PL/SQL procedure successfully completed.

DECLARE
   TYPE ridArray IS TABLE OF ROWID;

TYPE vcArray IS TABLE OF t.object_name%TYPE;

l_rids    ridArray;
   l_names   vcArray;

CURSOR c
   IS
      SELECT ROWID, object_name FROM t;
BEGIN
   OPEN c;

LOOP
      FETCH c
      BULK COLLECT INTO l_rids, l_names
      LIMIT 100;

FORALL i IN 1 .. l_rids.COUNT
         UPDATE t
            SET object_name = LOWER (l_names (i))
          WHERE ROWID = l_rids (i);

COMMIT;
      EXIT WHEN c%NOTFOUND;
   END LOOP;

CLOSE c;
END;

/

PL/SQL procedure successfully completed.

SQL> exec dbms_output.put_line((dbms_utility.get_cpu_time-:n)||‘ cpu hsecs‘);
26 cpu hsecs

PL/SQL procedure successfully completed.

2.Snapshot Too Old
   3.可重启的过程需要复杂的逻辑

使用自动提交

分布式事务

自治事务:允许创建一个事务中的事务,它能独立于其父事务提交或者回滚。

时间: 2024-12-24 15:37:20

Oracle事务的相关文章

oracle事务和锁

数据库事务概括 1. 说明 一组SQL,一个逻辑工作单位,执行时整体修改或者整体回退. 2.事务相关概念 1)事务的提交和回滚:COMMIT/ROLLBACK 2)事务的开始和结束 开始事务:连接到数据库,执行DML.DCL.DDL语句 结束事务: 1. 执行DDL(例如CREATE TABLE),DCL(例如GRANT),系统自动执行COMMIT语句 2. 执行COMMIT/ROLLBACK 3. 退出/断开数据库的连接自动执行COMMIT语句 4. 进程意外终止,事务自动rollback 5

Oracle 事务的開始与结束

事务是用来切割数据库活动的逻辑工作单元,事务即有起点,也有终点: 当下列事件之中的一个发生时,事务就開始了: 连接到数据库上,并运行了第一天 DML 语句: 当前一个事务结束后,又输入了另外一条 DML 语句: 当下列事件之中的一个发生时,事务就结束了: 运行 COMMIT 或 ROLLBACK语句: 运行一条 DLL语句,比如 CREATE TABLE 语句:在这样的情况下, 会自己主动运行 COMMIT 语句: 运行一条 DCL语句,比如GRANT语句:在这样的情况下,会自己主动运行COMM

Oracle 事务操作(事务的回滚与提交)

在看本文之前,请确保你已经了解了Oracle事务和锁的概念即其作用,不过不了解,请参考数据库事务的一致性和原子性浅析和Oracle TM锁和TX锁 1.提交事务 当执行使用commit语句可以提交事务.当执行了commit语句后,会确认事务的变化.结束事务.删除保存点.释放锁.在此之前,与当前事务相关的数据都会被加锁,直到当前事务进行了commit操作,如果在这个过程中有其他回话试图操作相关数据,(这些数据已经被当前事务加锁),那么其他回话会进行等待,或者直接返回错误. 注意:只有在提交事务之后

oracle事务知识点小结

DML语句流程 1 获取事务锁和ITL2 锁定候选行3 生成redo4 生成undo5 生成redo record写入log buffer并更改数据块 事务提交1 分配SCN2 更新事务表,将事务槽状态改为0x093 回收undo块4 创建commit redo record5 将redo从log buffer刷新6 释放表锁和行锁 锁一个事务由1个TX和若干TM组成,而回滚savepoint不会释放TX锁: ITL通过XID指向事务槽,进而指向undo记录,其UBA也指向undo记录:两者区别

oracle事务(转)

今天温习oracle事务,记录如下: 事务定义            事务是保持数据的一致性,它由相关的DDL或者DML语句做为载体,这组语句执行的结果要么一起成功,要么一起失败. 我们知道SQL92标准定义了数据库事务的四个特点: 原子性 (Atomicity) :一个事务里面所有包含的SQL语句是一个执行整体,不可分割,要么都做,要么都不做 一致性 (Consistency) :事务开始时,数据库中的数据是一致的,事务结束时,数据库的数据也应该是一致的 隔离性 (Isolation):  

Oracle事务隔离级别处理差异

Oracle事务隔离是事务读操作不同程度的数据隔离,分为READ_UNCOMMITTED.READ_COMMITTED(默认).SERIALIZABLE. Oracle事务隔离级别SERIALIZABLE,解决脏读.不重复读.幻读两个事务同时update相同记录时,第一个事务可执行,第二个事务阻塞,当第一个事务提交后,第二个事务抛出异常如图1.当第一个事务回滚后,第二个事务继续执行. 图1 Oracle事务隔离级别READ_COMMITTED,解决脏读两个事务同时update相同记录时,第一个事

Oracle事务隔离级别

oracle隔离级别 只有READ COMMITTED和 SERIALIZABLE 因为当有人对数据库的数据进行任何写操作(DML操作)时,Oracle数据库系统首先将原始的数据复制到回滚段中,之后才做相应的操作,在事务处理结束之前其他的用户可以读这些数据,但是读到的都是回滚段上的数据. 参考http://www.cnblogs.com/friends-wf/p/3746348.html Oracle事务隔离级别

Oracle事务之一:锁和隔离

Oracle事务之一:锁和隔离 一. 事务概述 事务管理是数据库处理的核心.数据库既要保证用户能并发地执行事务,还要保证数据库的一致性. 当第一条可执行的SQL开始执行,就隐形地开始了一个事务,直到遇到下面的几种情况: 1.Commit:提交事务. 2.RollBack:回滚. 3.DDL语句:执行和提交DDL语句结果前首先提交当前所有DML语句,成为隐式提交. 4.程序正常退出:自动提交. 5.不正常的程序失败:隐式回滚. 二.事务特性 事务的四个特性:A(原子性).C(一致性).I(隔离性)

Oracle 事务的开始与结束

事务是用来分割数据库活动的逻辑工作单元,事务即有起点,也有终点: 当下列事件之一发生时,事务就开始了: 连接到数据库上,并执行了第一天 DML 语句: 当前一个事务结束后,又输入了另外一条 DML 语句: 当下列事件之一发生时,事务就结束了: 执行 COMMIT 或 ROLLBACK语句: 执行一条 DLL语句,例如 CREATE TABLE 语句:在这种情况下, 会自动执行 COMMIT 语句: 执行一条 DCL语句,例如GRANT语句:在这种情况下,会自动执行COMMIT语句: 断开与数据库