Oracle PL/SQL(14) - 事务

Oracle是基于事务的,Oracle以用户事务来确保数据的完整性。一个事务即将一系列的数据操纵的sql语句作为一个逻辑单元,逻辑单元里面的单个操作要么全做,要么全部不做,以保证数据的完整性。

事务的特性:
原子性:事务是SQL中的最小执行单位,不能再进行分割。要么全部执行,要么全部不执行。
一致性:在事务操作前和事务操作后,数据必须处于一致状态。
隔离性:事务之间是相互隔离的,多个事务不会相互影响。
持久性:当事务提交后,数据则永久有效。

读取事务异常:
脏读:一个事务读取了另一个事务未提交的数据。
不可重复读:一个事务再次读取之前曾经读取过的数据时,发现该数据已经被另一个已提交的事务修改。
幻读:一个事务根据相同的查询条件,重新执行查询,返回记录中包含了与前一次执行查询返回的记录不同的行。

事务控制语句:
COMMIT:提交事务,对数据库的修改进行保存。
ROLLBACK:回滚事务,取消对数据库所做的修改。
SAVEPOINT:在事务中创建存储点。
ROLLBACK TO <SAVEPOINT>:将事务回滚到存储点。
SET TRANSACTION:设置事务的属性。
PRAGMA AUTONOMOUS_TRANSACTION:创建自治事务。

使用事务的步骤:
第1步、开启事务。在Oracle中,事务是在上一次事务结束以后,数据“第一次”被修改时自动开启。
第2步、进行(多次)数据操作(增、删、改)。
第3步、结束事务:事务结束有两种情况.
(1)事务被提交:
a.发出COMMIT命令。
b.执行DDL语句。如果DDL语句前面有DML语句,则Oracle会自动把前面的DML语句作为一个事务提交。
c.与Oracle断开连接,或退出PL/SQL Developer,事务会自动提交。
2)数据被撤销:
a.发出ROOLBACK命令.
b.服务器进程异常结束。
c.DBA停止会话。

1、设置事务隔离级别
Oracle / PLSQL中SET TRANSACTION语句的语法是:

SET TRANSACTION [ READ ONLY | READ WRITE ]
               [ ISOLATION LEVEL [ SERIALIZE | READ COMMITED ]
               [ USE ROLLBACK SEGMENT 'segment_name' ]
               [ NAME 'transaction_name' ];

READ ONLY - 可选的。 如果指定,它将事务设置为只读事务。
READ WRITE - 可选的。 如果指定,它将事务设置为读/写事务。
ISOLATION LEVEL - 可选的。 如果指定,它有两个选项:
ISOLATION LEVEL SERIALIZE - 如果事务尝试更新由另一个事务更新并未提交的资源,则事务将失败。
ISOLATION LEVEL READ COMMITTED - 如果事务需要另一个事务持有的行锁,则事务将等待,直到行锁被释放。
USE ROLLBACK SEGMENT - 可选的。 如果指定,它将事务分配给由'segment_name'标识的保存点,该段是用引号括起来的段名称。
NAME - 为'transaction_name'标识的事务分配一个名称,该事务用引号括起来。
例如:

-- 设置事务为只读事务,这在生成报告,账单等时特别有用
SET TRANSACTION READ ONLY NAME 'tran';
SELECT * FROM TEST;
COMMIT; -- 提交事务,只读事务也需要提交的哦

-- 指定事务的隔离级别
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE NAME 'tran';
-- SET TRANSACTION ISOLATION LEVEL READ COMMITTED NAME 'tran'; -- 事务默认的隔离级别是 READ COMMITTED
SELECT * FROM TEST;
COMMIT; -- 提交事务

-- 指定当事务失败时,将事务回滚到指定的回滚段
SET TRANSACTION USE ROLLBACK SEGMENT test NAME 'tran';
INSERT INTO TEST VALUES ('Scott');
ROLLBACK; -- 回滚事务

2、存储过程事务使用断点回滚
创建表

CREATE TABLE demo(description nvarchar2 (1000));
INSERT INTO demo VALUES ('test');

创建存储过程

CREATE OR REPLACE PROCEDURE rollback_point
IS
BEGIN
  UPDATE   demo
     SET   description = 'savapoint 1';
  SAVEPOINT p1;

  UPDATE   demo
     SET   description = 'savapoint p1';
  SAVEPOINT p2;

  ROLLBACK TO SAVEPOINT p1;
  --ROLLBACK; --会回滚整个事务处理。
  COMMIT;
EXCEPTION
  WHEN OTHERS
  THEN
     DBMS_OUTPUT.put_line ('demo');
END rollback_point;

保存点(SAVEPOINT) 是事务处理过程中的一个标志,与回滚命令 (ROLLBACK) 结合使用,主要的用途是允许用户将某一段处理回滚而不必回滚整个事务。
如果定义了多个 savepoint ,当指定回滚到某个 savepoint 时,那么回滚操作将回滚这个 savepoint 后面的所有操作。
如果不使用 ROLLBACK TO savepoint_name 而使用 ROLLBACK ,将会回滚整个事务处理。

3、自治事务与非自治事务
项目中,如果子程序 A 调用 B,那么 A 和 B 将在同一个事务中,A 或 B 中的任意一个 COMMIT 语句将会使 A 和 B 所做的所有更改全部提交。如果想让 B 在自己的事务中,无论 A 成功或失败都不影响 B,该如何处理呢?这里就要用到自治事务。

自治事务(autonomous transaction)是PL/SQL静态SQL的一个特性,它允许创建一个"事务中的事务",能独立于其主事务提交或回滚。利用自治事务,可以挂起当前执行的事务,开始一个新事务,完成一些工作,然后提交或回滚,所有这些都不影响当前所执行事务的状态。自治事务可以用来记录日志,记录计数值。

要创建一个自治事务,必须在匿名块的最高层或者存储过程、函数、数据包或触发的定义部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句。在这样的模块或过程中执行的SQL语句都是自治的。

以下例子演示自治事务如何工作
--创建测试表用于保存信息

Create table Msg (Msg varchar(50)) ;

--创建自治事务的存储过程

create or replace procedure AutoNomouse_Insert is
    PRAGMA AUTONOMOUS_TRANSACTION;--指示自治事务语句
    begin
            insert into Msg values('AutoNomouse Insert');
           commit;
   end;

--创建非自治事务存储过程

CREATE OR REPLACE Procedure NonAutoNomouse_Insert as
   begin
          insert into Msg Values('NonAutonomouse Insert');
          commit;
   end;

调用非自治事务的存储过程

begin
 insert into Msg Values('This Main Info');
 NonAutoNomouse_Insert;
 rollback;
end;

查询表中当前的数据

select * from msg;

结果为:
MSG


This Main Info
NonAutonomouse Insert

因为过程中有COMMIT;所以RULLBACK 不起作用;
由此得出:非自治事务中的COMMIT,ROLLBACK是会影响整个事务的。
下面我们看一个另外一种情况:
删除表中的数据,不COMMIT提交

delete msg;

再次调用非自治事务的存储过程

begin
   insert into Msg Values('This Main Info');
   rollback;  --这里加了ROLLBACK;
   NonAutoNomouse_Insert;
   rollback;
 end;

查询表中当前的数据

select * from msg;

结果为:
MSG


This Main Info
NonAutonomouse Insert
NonAutonomouse Insert

因为当前的调用是一个新的SESSION,前面的删除操作并没有提交,再次调用时被自动提交; 所以会看到三行数据。
删除表中的数据,COMMIT提交

delete msg;
commit;

查询表中当前的数据

select * from msg;

结果为:
MSG


可以看到这里是正常的提交;

下面看一下自制事务:

begin
insert into Msg Values('This Main Info');
AutoNomouse_Insert;
rollback;
end;

查询表中当前的数据

select * from msg;

结果为:
MSG


AutoNomouse Insert
结果是一行数据,可以看到自治事务过程中的commit只把它本身的事务提交了,而对于父事务的语句没有起到作用,而父事务中的rollback对自治事务中的语句也没有作用。

总结自主事务:
  1)、自主事务处理结果的变化不依赖于主事务处理的状态或最终配置。
  2)、自主事务处理提交或回滚时,不影响主事务处理的结果。
  3)、自主事务提交一旦提交,该自主事务处理结果的变化对于其他事务处理就是课件的。这意味着,用于可以访问已更新的信息,无需等待主事务处理提交。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342