Oracle 事务概述

这篇文章是参考老相老师的教学视频
http://v.youku.com/v_show/id_XNDAzOTI4MDQw.html
所做的学习笔记



1.事务(Transaction)的基本概念:
           事务由一组DML语句组成(insert/ update /delete);
           用commit; 就可以提交这个事务,也就是DML语句的改动写入数据库了.
           在commit之前使用Rollback就可以回滚DML语句造成的数据的改动.
           使用savepoint xx  可以保存保存点:
          使用Rollback to xx 回滚到保存点.

下面做个例子:
登陆sqlplus:
例如hr账户下有一张表CL_DEPT:


现在去查看事务的系统视图v$transaction, 是没有人任何记录的:


这时我执行一条DML语句(insert),但是仲未Commit:


这时再去查看v$transaction,已经出现一条record了
Oracle 事务概述 - 饥民 - 饥民2011
 
然后我再执行一条DML语句(update),
Oracle 事务概述 - 饥民 - 饥民2011

再查看v$transaction, 还是一条记录:
 Oracle 事务概述 - 饥民 - 饥民2011

注: v$transaction中的列:
XIDUSN:   undo segment number 回滚段序列号
UBABLK:  UBA(Undo block address) block number   回滚块序列号
UBAFIL:   UBA file number ...

也是就说,在commit 或 rollback之前,无论执行多少条DML语句.它们都属于同1个事务的.
注意: 若此时执行grant等(DDL)语句,  会自动触发commit, 所以不要写奇怪的代码啊.

在事务提交之前,其他用户是见不到你的改动,他们查询对应的表,得到的还是原来的数据:
Oracle 事务概述 - 饥民 - 饥民2011
 
这时我们commit
Oracle 事务概述 - 饥民 - 饥民2011
 
查看v$transaction, 事务消失, 表示事务结束了. 而其他用户就可以见到hr修改后的数据了.
这是默认的隔离级别,下面会提到
Oracle 事务概述 - 饥民 - 饥民2011
 
Oracle 事务概述 - 饥民 - 饥民2011

下面介绍save point:
我用hr账户再执行一条DML语句, 这样的话一条新的事务开始了.
Oracle 事务概述 - 饥民 - 饥民2011
 
这时我们执行1个保存点x1
Oracle 事务概述 - 饥民 - 饥民2011
 
然后再insert 1条record:
Oracle 事务概述 - 饥民 - 饥民2011
 
 这时我后悔了, 不想插入上面的那条record, 但是又想保留第一次插入的那条,
就可以用Rollback to savepointname 来回滚到保存点:
Oracle 事务概述 - 饥民 - 饥民2011
 
 如上图, 插入了60,TEL MADRID就是保存点前一条DML语句插入的.

但是虽然执行了Rollback 语句, 但是因为只是回滚到保存点,不是回滚整个事务,所以这个事务还没完成的!
Oracle 事务概述 - 饥民 - 饥民2011

这是可以继续rollback到前面的保存点, 或者commit..
 

2.事务的隐式commit和rollback

1.执行DDL语句(create table之类) 会隐式提交事务
2. session异常退出(包括数据库崩溃)会令session未提交的事务回滚.
3. session 正常退出 (输入 exit/关闭终端窗口/输入ctrl +D) 会隐式提交事务. 这个要注意啊

无论如何,要尽量避免事务的隐式的commit和rollback.


3事务的特性
事务包含4大特性ACID:
分别是:
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)

3.1 原子性(Atomicity):
    事务的原子性是指事务中所有的操作,要么都做, 要么都不做,保证数据库是一致的.
    例如:  A账户向B账户划账1000蚊,  则先将A减少1000,然后将B增加1000,这两个动作要么都提交,要么都回滚,不能只提交1个另1个无效,否则数据总账就变化了.


3.2 一致性(Consistency):
       一致性是指数据库在事务操作前和事务处理后, 其中的数据必须都满足业务规则约束.
        例如: A, B账户的总金额在转帐前和和转帐后必须一致,其中的不一致必须是短暂的,在事务提交后就会消失的.
        再如: 约定B账户不能多余1000元, 则转出1000成功, 而B账户转入失败, 最终由原子性得到---整个事务回滚.


3.3 隔离性(Isolation):
        隔离性是指数据库允许多个并发事务同时对数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行时导致数据的不一致.
   
        例如: 在A,B 之间转帐时, C同时向A转帐,若同时进行则A B之间的一致性不能满足,所以当A B事务执行时,其他事务不能访问(修改)当前相关的数据.

3.4 持久性(Durabiity)
       持久性表示为: 事务处理结束后,对数据的修改是永久的,即使系统故障也不会丢失
       在提交啊之前如果系统故障,则所有信息全部丢失,提交后数据存放在磁盘中,是永久性的.


4.事务的隔离级别.
级别:(只能用普通用户执行)
(串行)  SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
commit;

SET TRANSACTION ISOLATION LEVEL READ COMMITED;(默认)



4.1 SET TRANSACTION ISOLATION LEVEL READ COMMITED;(默认)
我们知道默认的事务隔离级别是这样的:
如上面HR 和 scott的例子
Session B见不到 Session A提交前修改的数据, 但Session A一旦提交, B马上就见到了.


4.2 (串行)SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
但是我们执行上面那条语句后再试下:(用普通用户执行)
这时scott 执行将事务隔离化设为串行:
Oracle 事务概述 - 饥民 - 饥民2011
 

 

这时HR 向cl_dept插入一条数据:
Oracle 事务概述 - 饥民 - 饥民2011
 
这时Scott去查看这张表,当然是见不到HR未commit的新数据行的:
Oracle 事务概述 - 饥民 - 饥民2011
 
这时HR commit这条transaction:
Oracle 事务概述 - 饥民 - 饥民2011
 
再去scott那条session查看对应表, 发现即使hr commit了事务,  scott还是见不到修改后的数据:
Oracle 事务概述 - 饥民 - 饥民2011
 
那什么时候scott才能看到Hr修改的数据呢,  这时需要scott 执行commit...
Oracle 事务概述 - 饥民 - 饥民2011

也就是说scott执行了SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
之后,相当与自己开 1个事务, 在这个事务commit之前,  他见不到其他session的任何的数据改动.

这个特性有时在不想见到数据改动的情况有用,例如提取数据做报表, 需要一定时间的静态数据.



 
5.另外两条 Set transaction 语句:
5.1 SET TRANSACTION  READ ONLY;
执行了上面那个语句, 你就不能执行DML语句了.. 也就是不能修改数据.
除非你执行rollback 或 commit;


5.1 SET TRANSACTION  READ WRITE;
这个是默认的,没什么可说啦~



posted @ 2013-04-02 00:56  Gateman  阅读(377)  评论(0编辑  收藏  举报