Oracle数据库相关事务(一)
Oracle数据库相关事务(一)
目录
1.事务的相关概念
在形式上,事务是由ACID属性标识的。ACID是一个简称,每个事务的处理必须满足ACID原则,即原子性 (Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)
- 原子性。原子性意味着每个事务都必须被认为是一个不可分割的单元(假设一个事务由两个或者多个任务 组成,其中的语句必须同时成功才能认为事务是成功的。如果事务失败,系统将会返回到事务以前的状态)。
- 一致性。不管事务是完全成功完成还是中途失败,当事务使系统中的所有数据处于一致的状态时存在一致 性(同一个账户在不同银行取钱,事务都是保持一致性的,不然事务之间将发生乱套)。
- 隔离性。隔离性是指每个事务在它自己的空间发生,和其他发生在系统中的事务隔离,而且事务的结果只 有在它完全被执行时才能看到(事务之间的空间是相互独立的,互不影响)。
- 持久性。持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的(即使系统崩溃,一个提 交的事务仍然存在。当一个事务完成,数据库的日志已经被更新时,持久性就开始发生作用)。

例如上面流程,如果操作1成功之后,那么继续后面的操作2,但是如果操作1失败之后,那么将回退到开始状态,撤销在失败之前的所有变化,删除所有不完整的数据,避免不一致性;任何任务的失败都会导致整个事务被撤销,系统返回到以前的状态。
2.事务的处理
事务是隐式自动开始的,不需要用户显式地使用语句来开始一个事务。当发生如下事件时, 事务就自动开始了。
- 连接到数据库,并开始执行第一条DML语句;
- 前一个事务结束或者执行一条自动提交事务的语句。
当用户执行下面的语句时,Oracle系统则认为事务结束:
- 用户执行COMMIT语句提交事务,或者执行ROLLBACK语句撤销了事务;
- 用户执行了一条DDL语句,如CREATE、DROP或ALTER语句;
- 用户执行了一条DCL语句,如GRANT、REVOKE、AUDIT、NOAUDIT等;
- 用户断开与数据库的连接,这时用户当前的事务会被自动提交;
- 执行DML语句失败,这时当前的事务会被自动回退。
提示:其实上面的内容在我们呢前面对Oracle数据库进行操作的过程已经执行过了。
(1)提交事务
- 在回退段的事务表内记录这个事务 已经提交,并且生成一个唯一的系统改 变号(SCN)保存到事务表中,用于唯一 标识这个事务。
- 启动LGWR后台进程,将SGA区重做日 志缓存的重做记录写入联机重做日志文件, 并且将该事务的SCN也保存到联机重做日志 文件中。
- 释放该事务中各个SQL语句所占用的系统资源。
- 通知用户事务已经成功提交。
--插入数据
insert into xsb
values('151305','向前','男','1999-5-6','计算机',49);
--查询数据
select *
from xsb
where sid='151305';
--提交事务
commit;
(2)事务回退
如果在数据库修改的过程中,用户不打算保存对数据所做的修改,可以使用ROLLBACK语句回退整个事务, 将数据库的状态回退到上一个提交成功的状态。
回退的过程:
- Oracle通 过使用回退段 中的数据撤销 事务中所有 SQL语句对数 据库所做的修改。
- Oracle 服务进程释 放事务所使 用的资源。
- 通知 用户事务回 退成功。
例子1:比如我现在对学生表XSB删除一个学生的信息,但是由于删除了信息,需要恢复数据,那么可以使用回退的方式。

delete
from scott.xsb
where sid='151305';


回退:
rollback

(3)回退部分事务
在事务的执行过程中,可以通过建立保存点将一个较长的事务分隔为几部分。通过保存点,用户可以在一个 长事务中的任意时刻保存当前的工作,随后用户可以选择回退保存点之后的操作,保存点之前的操作被保留。
- 设置保存点:SAVEPOINT <保存点名称>;
- 如果要回退到事务的某个保存点,则使用ROLLBACK TO语句: ROLLBACK TO [SAVEPOINT] <保存点名称>
提示:ROLLBACK TO语句只会回退用户所做的一部分操作,事务并没有结束。直到使用COMMIT或ROLLBACK命令 以后,用户的事务处理才算结束
例子:比如我们现在添加学生表XSB表中的n条学生的信息,可是当进行到第k条信息的时候,我们设置一个保存点,以便于我们回退到这里。
--插入第一条数据
insert into xsb
values('151304','李子','男','1999-5-6','计算机',49);
--设置一个保存点
SAVEPOINT myinto;--当我们插入第二条数据之后,发现数据有问题,得回退到第一条数据
insert into xsb
values('151306','程蒙','男','1999-5-6','计算机',49);

可以看到已经将上面的两条数据插入到表中,但是现在需要回退到第一条数据之后。
rollback to myinto;

现在来做一个测试:首先向学生表XSB中插入一条数据,并且设置保存点,之后再删除这条数据,最后回退到设置的保存点处,观察最后发生的情况。
首先插入数据:
--插入第一条数据
insert into xsb
values('151306','程蒙','男','1999-5-6','计算机',49);
--设置一个保存点
SAVEPOINT myinto;

--删除刚才插入的数据
delete
from xsb
where sid='151306';

现在执行回退操作,并且回退到刚才的保存点并提交事务;
rollback to myinto;
commit;

原因,主要是由于Oracle中系统执行部分回退事务的过程:
- Oracle通过使用回退段中 的数据,撤销事务中保存点之后 的所有更改,但保存保存点之前 的更改。
- Oracle服务进程释放保存点之 后各个SQL语句所占用的系统资源, 但保存保存点之前各个SQL语句所占 用的系统资源。
- 通知用户回退到保存点的 操作成功。
- 用户可以继续执行当前的事务。
提示:也就是我们刚才在插入数据之后设置了保存点,虽然后面执行了删除的操作,但是由于设置了保存点,而Oracle数据库中的部分回退机制是撤销事务保存点之后的所有更改,保存保存点之前的所有更改,所以当我们执行提交事务之后,那条数据其实还在。
(4)自治事务
自治事务(Autonomous Transaction)允许用户创建一个“事务中的事务”,它能独立于其父事务提交或回滚。 利用自治事务,可以挂起当前执行的事务,开始一个新事务,完成一些工作,然后提交或回滚,所有这些都 不影响当前执行事务的状态。同样,当前事务的回退也对自治事务没有影响。
应用:
- 顶层匿名块;
- 本地(过程中的过程)、独立或打包的函数和过程;
- 对象类型的方法;
- 数据库触发器。
注意:自治事务在DECLARE块中使用PRAGMA AUTONOMOUS_TRANSACTION语句来声明,自治事务从PRAGMA后 的第一个BEGIN开始,只要此BEGIN块仍在作用域,则都属于自治事务。结束一个自治事务必须提交一个 COMMIT、ROLLBACK或执行DDL。
例子:首先删除学生表的一条信息,接着定义一个自治事务,最后进行回退的操作,观察发生的情况。
--首先执行删除操作
delete
from xsb
where sid='151109';
--自治事务插入操作
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
insert into xsb
values('151108','张剑','男','1999-7-8','通信工程',57);
commit;
END;--执行回退操作
rollback;

解释:当我们删除表中的一条信息的,使用回退操作,那么会恢复到原来的数据,这是没有什么问题的。可是我们在使用回退之前也使用了插入的操作,按理来说应该是插入数据的操作也应该回退,而结果显示没有,这是因为在插入数据操作中声明了这是自治事务的操作,所以这个插入数据的操作独立于其父事务提交或回滚,因此不会影响到当前执行的回退操作。
例子2:定义一个触发器,并且在触发器中进行插入,更新和删除数据操作之后,进行提交,可是在触发器中不能直接使用commit提交事务操作,所以需要定义为自治事务,这样触发和提交就不会受到影响。
第一步:首先创建一个用来记录从学生表删除的数据表DXSB:
CREATE TABLE DXSB(
sid VARCHAR(20) NOT NULL PRIMARY KEY,
sname VARCHAR(20) NOT NULL,
sex char(2) NOT NULL,
birthday VARCHAR(20),
profession VARCHAR(20),
score VARCHAR(20)
);
第二步:创建一个触发器TrigDemo
CREATE OR REPLACE TRIGGER TrigDemo
BEFORE DELETE ON XSB FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO DXSB
values(:OLD.sid,:OLD.sname,:OLD.sex,:OLD.birthday,:OLD.profession,:OLD.score);
COMMIT;
END;
第三步:对学生表XSB执行删除操作。
delete
from xsb
where sid='151306';

从XSB表成功删除并且将删除的信息存放在了DXSB表中。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)