oracle事务特性详解

原子性

事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。

-- 创建表
create table account_money
(
  id    number(4) not null,
  name  varchar2(4) not null,
  money number(5,2) not null
)
;
-- 增加一个检查约束
alter table account_money
  add constraint CK_money
  check (money>=0);

--向张三这个账号增加数据
insert into ACCOUNT_MONEY (ID, NAME, MONEY)
values (1001, ‘张三‘, 500.00);
insert into ACCOUNT_MONEY (ID, NAME, MONEY)
values (1002, ‘张三‘, 1.00);

增加后的表如下:

ID    NAME    MONEY
1    1001    张三    500.00   
2    1002    张三    1.00

以下为oracle事务处理

BEGIN
  --从张三的1001账户转入张三的1002账户
  UPDATE account_money a SET a.Money=a.Money-600 WHERE a.Id=‘1001‘;
  UPDATE account_money a SET a.Money=a.Money+600 WHERE a.Id=‘1002‘;
  COMMIT;--提交事务
EXCEPTION --异常处理
  WHEN OTHERS THEN ROLLBACK;--出现异常就回滚
  Dbms_Output.Put_Line(‘转账异常,转账失败‘);  

在上述代码中,因为账户设置了检查约束,当账户小于0时,就会出现异常,如果不进行事务异常处理,那么第二条更新语句会被执行。当做了事务异常处理后,当出现异常就会回滚。

一致性

在事务操作前后,数据必须处于一致状态。是一个业务规则约束的范畴。

同样使用以上的表来做以说明:

DECLARE
  account_a account_money.Money%TYPE;
  account_b account_money.Money%TYPE;
BEGIN
  SELECT a.money INTO account_a FROM account_money a WHERE a.Id=‘1001‘;
  SELECT a.money INTO account_b FROM account_money a WHERE a.Id=‘1002‘;
  Dbms_Output.Put_Line(‘转账前A账户余额:‘||account_a);
  Dbms_Output.Put_Line(‘转账前B账户余额:‘||account_b);
  Dbms_Output.Put_Line(‘转账前总余额:‘||(account_a+account_b));
  UPDATE account_money SET money=money-100 WHERE ID=‘1001‘;
  UPDATE account_money SET money=money+100 WHERE ID=‘1002‘;
  COMMIT;
  SELECT a.money INTO account_a FROM account_money a WHERE a.Id=‘1001‘;
  SELECT a.money INTO account_b FROM account_money a WHERE a.Id=‘1002‘;
  Dbms_Output.Put_Line(‘转账后A账户余额:‘||account_a);
  Dbms_Output.Put_Line(‘转账后B账户余额:‘||account_b);
  Dbms_Output.Put_Line(‘转账后总余额:‘||(account_a+account_b));
  EXCEPTION
    WHEN OTHERS THEN
      Dbms_Output.Put_Line(‘转账失败,业务取消‘);
  SELECT a.money INTO account_a FROM account_money a WHERE a.Id=‘1001‘;
  SELECT a.money INTO account_b FROM account_money a WHERE a.Id=‘1002‘;
  Dbms_Output.Put_Line(‘停止转账后A账户余额:‘||account_a);
  Dbms_Output.Put_Line(‘停止转账后B账户余额:‘||account_b);
  Dbms_Output.Put_Line(‘停止转账后总余额:‘||(account_a+account_b));
END;

执行上段代码,

执行第一遍:

转账前A账户余额:500
转账前B账户余额:1
转账前总余额:501
转账后A账户余额:400
转账后B账户余额:101
转账后总余额:501

执行第二遍:

转账前A账户余额:400
转账前B账户余额:101
转账前总余额:501
转账后A账户余额:300
转账后B账户余额:201
转账后总余额:501

执行第三遍:

转账前A账户余额:300
转账前B账户余额:201
转账前总余额:501
转账后A账户余额:200
转账后B账户余额:301
转账后总余额:501

。。。。。。

当执行第5遍时:A账户的余额为0,如果再执行会出现象呢?

转账前A账户余额:100
转账前B账户余额:401
转账前总余额:501
转账后A账户余额:0
转账后B账户余额:501
转账后总余额:501

执行第6遍,第7遍…………:

转账前A账户余额:0
转账前B账户余额:501
转账前总余额:501
转账失败,业务取消
停止转账后A账户余额:0
停止转账后B账户余额:501
停止转账后总余额:501

我们会发现,当我们做事务处理后,总额不会发生变化,当出现异常就不会再执行(或者说回滚)!

隔离性

对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不是以任何方式依赖于或影响其它事务。

每个事务是独立的,我们在PL/SQL中新建两个SQL窗口就以可以做两个事务处理。

我们还是使用以上表,表内容如下:

ID    NAME    MONEY
1    1001    张三    0.00
2    1002    张三    501.00

第一个SQL窗口:

第二个SQL窗口:

输入:SELECT * FROM account_money;这条查询语句,我们会发现,第一个SQL窗口没有执行之前的数据。

如果我们也在第二个SQL窗口使用update更新数据会怎么样呢?

UPDATE account_money SET money=money+300 WHERE ID=‘1001‘;
SELECT * FROM account_money;

他会等待第一个SQL窗口提交事务才会有更新结果!

这时我们提交第一个SQL窗口的事务,我们会看到,两个窗口的结果都发生变化。

我们再提交第二个SQL窗口的事务(在第一个SQL窗口事务没有提交之前是不能提交第二个窗口的事务的),结果也同上图!

持久性

事务完成后,它对数据库的修改被永久保存下来。

时间: 2024-10-16 08:50:38

oracle事务特性详解的相关文章

Oracle 11g数据库详解(2015-1-18更新)

Oracle 11g数据库详解 整理者:高压锅 QQ:280604597 Email:[email protected] 大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的 1   简介 数据库操作主要有以下几步: 1.  启动.停止数据库 2.  连接.断开数据库 3.  创建.修改.删除数据库用户 4.  表空间 5.  新建.修改.删除表 6.  查询.插入.修改.删除表数据 7.  新建.修改.删除视图 8.  新建.修改.删除存储过程 9.  新建.修改.删除触发

Oracle 11g数据库详解(2015-02-28更新)

Oracle 11g数据库详解 整理者:高压锅 QQ:280604597 Email:[email protected] 大家有什么不明白的地方,或者想要详细了解的地方可以联系我,我会认真回复的 1   简介 数据库操作主要有以下几步: 1.  启动.停止数据库 2.  连接.断开数据库 3.  创建.修改.删除数据库用户 4.  表空间 5.  新建.修改.删除表 6.  查询.插入.修改.删除表数据 7.  新建.修改.删除视图 8.  新建.修改.删除存储过程 9.  新建.修改.删除触发

ORACLE物化视图详解

一.物化的一般用法物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,oracle都实际上转换为视图SQL语句的查询.这样对整体查询性能的提高,并没有实质上的好处. 1.物化视图的类型ON DEMAND.ON COMMIT.二者的区别在于刷新方法的不同,ON DEMAND顾名思义,仅在该物化视图"需要"被刷新了,才进行刷新(REFRESH),即更新物化视图,以保证和基表数据的一

spring声明式事务配置详解

spring声明式事务配置详解 君子不器 2013年06月16日 编程世界 5273次阅读 查看评论 理解Spring的声明式事务管理实现 本节的目的是消除与使用声明式事务管理有关的神秘性.简单点儿总是好的,这份参考文档只是告诉你给你的类加上@Transactional注解,在配置文件中添加('<tx:annotation-driven/>')行,然后期望你理解整个过程是怎么工作的.此节讲述Spring的声明式事务管理内部的工作机制,以帮助你在面对事务相关的问题时不至于误入迷途,回朔到上游平静

ORACLE用户PROFILE详解

ORACLE用户PROFILE详解   一.官网说明 Oraclerecommends that you use the Database Resource Manager rather than the SQLstatement to establish resource limits. The Database Resource Manager offers amore flexible means of managing and tracking resource use. Purpose

oracle rac IP详解

rac环境下vip/public/private IP的区别 每个节点要2块网卡, 3个IP,虚拟IP或者叫做业务IP,单个网卡当掉可以"漂"到其他网卡是继续提供服务 在Oracle RAC环境下,每个节点都会有多个IP地址,分别为Public/Private/Vip,这三个IP到底有啥区别呢?分别用在那些场合呢?来看看老外的回答. 1. private IP address is used only for internal clustering processing (Cache

http协议及httpd特性详解

前言 随着互联网的迅猛发展和网络的普及,各类网站层出不穷,网站也成为企业宣传和实力展现的主要途径之一,说到网站就不得不说一下web服务了,现在比较流行的web服务还是当属Apache即httpd.本文将详解http协议及httpd的特性. http协议详解 http协议 http: Hyper Text Transfer Protocol 超文本传输协议 传输文本:HTML html: Hyper Text Mark Language 超文本标记语言 html文档的生成方式 静态:纯html格式

Oracle AWR 报告详解

转自:http://blog.csdn.net/laoshangxyc/article/details/8615187 持续更新中... Oracle awr报告详解 DB Name DB Id Instance Inst num Startup Time Release RAC ORCL 1295334343 orcl 1 09-1月 -12 18:01 11.2.0.1.0 NO DB Name :数据库名 DB Id :数据库Id(获取方法select dbid from v$databa

oracle HA 高可用性详解(之二,深入解析TAF,以及HA框架)

oracle HA 高可用性详解(之一,client.server端服务详解):http://write.blog.csdn.net/postedit 我们已经看到TAF是的Oracle的会话能够自动重新连接,需要说明的是,这个能力是基于OCI的,是OCI的一个功能,JDBC Thin Driver无效,因为这种驱动不是构建在OCI库上的. 虽然这个功能发起于RAC,但TAF并不局限于RAC,单实例.DG环境都可以享受这个好处.Oralce声称其TAF能够保证用户会话自动的转移到另一个实例上.这