Oracle之事务
一,oracle的事务:
是指对数据操作的一系列动作的统称.即:事务的任务便是使数据库从一种状态变换成为另一种状态,这不同于文件系统,它是数据库所特用的。
事务有四大特性(ACID):
1,原子性(atomicity),
事务中的所有任务要么全部成功,要么全部失败.不能存在部分成功,部分失败.
比如银行转账,A向B转200元,A账户余额少200元,B账户余额多200元.不能出现A账户少200元而B账户余额没多出200元.
2,一致性(consistency),
事务将数据库从一种一致状态转变为下一个一致状态.
比如转账,A账户和B账户都成功的更新了余额,则这个转账操作才是成功完成的,如果任何一个操作发生而另一个没有发生,
就会导致数据出现不一致,而使用事务可以确保数据的一致性.
3,隔离性(isolation),
一个事务的影响在该事务提交到数据库前对其他事务都是不可见得.
比如转账,当将A账户的余额减少时,由于还没有更新B账户,事务没提交,其他用户在查看A账户时,
不会看到A账户余额已经减少,只有在转账成功完成时,才会看到效果,这使得事务好像是串行执行的一样
4,持久性(durability),
事务一旦提交,其所做的更改就是永久性的.
数据库通过其恢复机制,确保在事务中所作的更改不会丢失.
事务结束的几种情况:
1,遇到commit,rollback语句时,提交或者回滚事务.
2,当用户退出Oracle工具时,
3,当机器失效或者是系统崩溃时.
二,事务的管理
commit,提交自上一次commit或者是rollback一来,所有当前的改变,并且释放所有的锁
rollback,回滚自上一次commit或者是rollback一来,所有当前的改变,并且释放所有的锁
rollback to savepoint ,回滚改变到一个已经保存的保存点,并且释放所有该范围内的锁
savepoint,建立一个保存点,允许完成部分回滚操作
set transaction,允许开始一个只读或者读写回话,建立一个隔离级别,或者将当前的事务赋给一个特定的回滚段
lock table,允许使用特定的模式锁定整个数据库表,这将覆盖默认行级别的锁定,
使用commit提交事务:
oracle的事务和sql sever 有着很大的区别,在sql server中,如果用户执行了一条Insert语句,sql server会自动的开始一个事务然后提交,或者是执行begain tranction 来显示的开启一个语句块事务,但是Oracle 的事务是隐式的,也就是说自上次提交或者回滚以来的任何对数据库的操作都会导致有个新的事务开始.除非用户显式的使用commit或者是rollback提交或者回滚事务,则对数据库的修改只会保存在当前会话的撤销段中,并不会对数据库造成永久性的更改.
当一个事务开始时,Oracle会为这个事务分配一个可用的UNDO字段,也就是撤销字段,用来记录新的事务的更改,当第一个DML(insert,update,delete)语句执行时,Oracle除了分配撤销字段外,还会分配事务表槽和事务ID,事务ID对于整个事务来说是唯一的.
在sqlplus中执行一条update语句:
update emp e e.sal=8000 where e.empno=7336;
接着执行一条sql:
select XID as '事务ID',XIDUSN as 'UNDO' ,XIDSLOT as '事务槽', XIDSQN as 'seq', STATUS as '事务状态' from v$transaction
当用户开启一个事务时,可以看到一个具体的事务ID,并且分配了指定的UNDO段和事务槽,当前事务的状态是激活状态,v$transaction动态的数据字典视图,当事务被提交或者是回滚后,位于该视图基表中的事务信息会被自动删除.
当一个事务需要更改持久化到数据库中时,可以使用Oracle提供的Commit,
当使用Commit时,其实是起到了两个作用:
1,对DML语句进行更改,会被持久到数据库中,其他用户也可以查询的到
2,释放作用于表或行上的所有锁,同时清除自上一次提交或回滚以后的所有的保存点
Commit的语法如下:
commit [work] [comment text];
关键字work 是为了增加可读性,其实是没啥作用的.
comment是用来添加注释的.comment的text(文本内容)长度不要超过50个字符.
比如:commit comment '提交数据,保证数据的正确性';
当一个事务产生时,Oracle除在UNDO段中产生撤销记录外,还会在重做日志缓冲区中产生REDO记录,REDO记录用于重放事务,以便于在出现数据故障或者需要回复数据库时对数据所做的修改,并且会修改SGA的数据库缓冲区,在提交事务时,实际会做3件事:
1,在重做日志记录中,所修改的表被标记上所提交事务的唯一系统更改号SCN
2,LGWR日志写进程将事务的未写入磁盘的REDO信息及事务的SCN从重做日志缓冲区写到磁盘上的重做日志文件,完成提交
3,释放DML操作所分配的锁,Oracle标记事务完成.
注意:
提交数据只是将重做日志缓冲区中的信息刷新输出到磁盘,并不是将数据库高数缓存中已经修改的快立即写入到磁盘中,因此,commit语句通常执行的比较快,即便是做了较大的修改,commit语句也往往会立即执行完成.
使用rollback回滚事务:
如果要撤销事务中对数据库的操作,可以使用bollback语句,该语句会撤销自事务开始以来sql语句所作的更改.
语法如下:
rollback [work][TO [savepoint] savepoint_name];
rollback 回滚语句与commit不一样,commit在提交时,commit在提交数据时,数据库只会将重做日志缓冲区的数据写入到联机重做日志文件,并不会立即将缓冲区高速缓存中的数据块写入到磁盘,而rollback需要物理的将UNDO表空间中的撤销记录进行回滚,回滚是个物理操作,他需要逆向的执行在UNDO段中写入的数据,并且释放所有的锁,对于一个较大的事务来说,回滚的开销会很大,一般很少对一个大的事务进行回滚,除非操作错误,或者sql出错.
使用savepoint保存点:
保存点实际会完成三个工作:
1,从保存点以后所做的所有操作都被撤销,并且rollback之后的保存点也会被清除,但是当前的保存点未被释放,如果需要,可以再次撤销该保存点
2,自该保存点以后sql语句所需的锁和资源都会被释放
3,虽然撤销到保存点,但是并不是结束整个事务,sql会处于挂起状态.
事务的隔离级别:
保证一个事务在提交前其他事务看不到相应事务所做的操作
使用SET TRANSACTION 设置事务的属性:
语法如下:
set trancaction parameter
read only :只读,此事务中执行任何Insert ,delete,uodate语句都属于是非法 操作,对于这些事务不需要回滚
read write 读写事务,这是Oracle默认的设置.
isolation level :用来设置事务的隔离级别,即规定在事务中如何处理DML事务,可以设置Serializable和READ committed,这两个选项
SERIAIZABLE 选项会使得对已经修改但是还没提交的数据对象的DML事务失败,
READ Committed 是对已经修改但没有提交的数据库对象的DML事务进行修改时,会等待前面的DML锁消失,这是Oracle的默认特性,ISOLOATION level 的基本操作语法如下:
SET TRANSACTION ISOLATION level serializable--设置序列隔离级别
SET TRANSACTION ISOLATION READ committed--设置读提交隔离级别
注意:
由于SET TRANSACTION 必须是事务中的第一条语句,因此实例先使用Rollback 回滚事务,然后调用update 语句,可以见到Pracle 抛出错误,表示不能在一个只读事务上进行DML操作,但是可以查询.
在默认情况下,事务是可读可写的,是因为隔离级别默认是READ WRITE ,所以才可以进行DML操作.
如果设置为SET TRANSACTION ISOLATION level serializable,两个sql窗口都执行update语句,第二个窗口会被锁着,如果窗口1commit后,2窗口仍然会报错.