数据库版本

SYS@LEO1>select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 - Production

事务那些事儿()

1.事务:事务可以理解为一系列动作的逻辑单位,我们把这一系列动作叫做一个事务。这一系列动作要持续完成的,中间不可以断。

2.事务与锁的关系:事务的并发是由锁来控制的(同一时间只允许一个会话来操作),锁是数据库并发操作中最常见的保护机制。不同的数据库锁机制也有很大差异。

Oracle与SQL server的区别

Oracle                                              SQL server

可以实现读/写互不阻塞,利用undo实现读会阻塞写,写也会阻塞读,用查询锁定实现

锁作为数据块一种属性存在,没有锁管理器使用锁管理器控制事务并发,代价昂贵

主张按照业务需求确定事务边界提倡尽快提交事务

3.事务控制:commit&rollback都是一个事务的结束

我们可以在一个事务生命周期的一半设置一个save point,遇到问题我们可以回退到这个保存点而不需要把事务全部回退,从而更加精细化的控制事务。

4.分布式事务:

举一个例子,说明save point的用处,给出SQL演示。

保存点save point:我们可以理解为放置在事务中的一个“标签点”,防止一部分操作错误导致整个事务重新执行。我们只需要回退到这个标签点的位置继续重做后面的操作即可。

实例

铃铃铃。。。下课铃响了,刚刚上完tiger的“大数据探索之旅”课程,tiger老师在下课后给大家留了一道小作业,现在想把作业成绩给大家登记下来。

LEO1@LEO1>drop table leo1 purge;                   清空环境

Table dropped.

LEO1@LEO1>create table leo1 (x int);                  创建成绩表

Table created.

LEO1@LEO1>insert into leo1 values(10);                学号1的同学成绩为10

1 row created.

LEO1@LEO1>select * from leo1;

X

----------

10

LEO1@LEO1>savepoint leo_1;                        为了防止误操作,我们随机做几个保存点

Savepoint created.

LEO1@LEO1>insert into leo1 values(20);                学号2的同学成绩为20

1 row created.

LEO1@LEO1>insert into leo1 values(30);                学号3的同学成绩为30

1 row created.

LEO1@LEO1>select * from leo1;                       成绩表中有3条记录

X

----------

10

20

30

LEO1@LEO1>savepoint leo_2;                         保存点2

Savepoint created.

突然发现把学号2和学号3的成绩登记错了,现在只想回退到学号1登记之后的位置,如果全回退所有的工作都白做了,聪明的tiger老师不会这么干的,此时我们标记的保存点派上用场了,我们只需回退到leo_1即可。

LEO1@LEO1>rollback to leo_1;

Rollback complete.

这里说明一点,虽说回退到了leo_1保存点,但这个事务还没有顺利结束,其他会话不可见,只有commit之后才表示事务完整结束。

LEO1@LEO1>select * from leo1;                       ok此时继续重做后面的操作就完事大吉

X

----------

10

LEO1@LEO1>commit;

Commit complete.

写一个用于审计的触发器,利用自治事务技术。

自治事务:一个事务中嵌套另一个事务,彼此是相互独立的,互不干涉。

应用场合:需要独立处理一件事情,例如独立审计过程。

实例

我们经常会在淘宝上买东西,渐渐我们自己也想开个小铺,我们有一个产品明细表product,还有一张审计表product_audit。审计表里记录着我们产品的变化情况(我们在审计的过程中使用自治事务技术),我们只需要知道产品还剩余多少即可。

Product表

LEO1@LEO1>create table product (id int,name varchar2(20),num int,cost int);

Table created.

LEO1@LEO1>insert into product values(1,'apple',10,10);            插入5条记录

1 row created.

LEO1@LEO1>insert into product values(2,'orange',20,20);

1 row created.

LEO1@LEO1>insert into product values(3,'banana',30,30);

1 row created.

LEO1@LEO1>insert into product values(4,'mango',40,40);

1 row created.

LEO1@LEO1>insert into product values(5,'KFC',50,50);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from product;

ID NAME                        NUM       COST

---------- -------------------- ---------- ----------

1 apple                        10         10

2 orange                       20         20

3 banana                       30         30

4 mango                        40         40

5 KFC                          50         50

Product_audit表

LEO1@LEO1>create table product_audit (id int,name varchar2(20),remain_num int);

Table created.

创建审计触发器tib_product,当product表有update动作之后被触发,会把剩余数记录到product_audit表里

LEO1@LEO1>create or replace trigger tib_product after update on product for each row

declare

pragma autonomous_transaction;        这句话声明下面的事务是一个自治事务,独立存在的

tib_id         number;

tib_name       varchar2(20);

tib_remain_num number;

begin

tib_id :=:old.id;

tib_name :=:old.name;

tib_remain_num :=:new.num;

insert into product_audit values (tib_id,tib_name,tib_remain_num);

commit;

end;

/

2    3    4    5    6    7    8    9   10   11   12   13   14

Trigger created.

每个产品我们都卖了一半,更新5条记录

LEO1@LEO1>update product set num=5  where name='apple';

1 row updated.

LEO1@LEO1>update product set num=10 where name='orange';

1 row updated.

LEO1@LEO1>update product set num=15 where name='banana';

1 row updated.

LEO1@LEO1>update product set num=20 where name='mango';

1 row updated.

LEO1@LEO1>update product set num=25 where name='KFC';

1 row updated.

LEO1@LEO1>select * from product;

ID NAME                        NUM       COST

---------- -------------------- ---------- ----------

1 apple                         5         10

2 orange                       10         20

3 banana                       15         30

4 mango                        20         40

5 KFC                          25         50

此时我们把改变的数据进行回滚,看看审计表有没有影响

LEO1@LEO1>select * from product;                           产品明细表成功回滚,事务结束

ID NAME                        NUM       COST

---------- -------------------- ---------- ----------

1 apple                        10         10

2 orange                       20         20

3 banana                       30         30

4 mango                        40         40

5 KFC                          50         50

这时我们再看看审计表有没有记录着产品的剩余情况

LEO1@LEO1>select * from product_audit;               good很好,完全记录下来了

ID NAME                 REMAIN_NUM

---------- -------------------- ----------

1 apple                         5

2 orange                       10

3 banana                       15

4 mango                        20

5 KFC                          25

我们登陆一个新会话,如果新会话也可以正常访问到product_audit表说明我们设计的自治事务完整结束

LEO1@LEO1>select distinct sid from v$mystat;

SID

-----------------

142

LEO1@LEO1>select * from product_audit;                good可以正常看到测试非常成功

ID NAME                 REMAIN_NUM

---------- -------------------- ----------

1 apple                         5

2 orange                       10

3 banana                       15

4 mango                        20

5 KFC                          25

小结:通过上面的实验我们可以感受到自治事务在某些场景下可以给我们带来很大方便,通过自治事务我们可以很好的实现事务隔离。

请画出一个分布式事务操作的原理图。

分布式事务:所谓分布式事务就是发生在多台数据库之间的事务操作,它们通过dblink实现事务处理。分布式事务要比单机事务复杂的多,其中涉及到网络问题操作系统问题数据库问题等等。具体操作原理请参考下图所示

下方是三个数据库A B C,它们之间是通过dblink连接进行分布式事务操作。

分布式事务之术语

Client:访问其他数据库的节点

Database:接收来自其他数据库访问的节点,例如 A库->访问->B库,那么A就是client端,B就是database端

Global coordinator:发起分布式事务的节点

Local coordinator:处理本地事务的节点

Commit point:被global coordinator指定为首先提交or回滚的事务节点,就是第一个提交的节点叫提交点,其他节点按顺序完成提交。

数据库集群中每个库都有一个commit_point_strength提交点权重参数,Oracle选取权重最大的数据库为集群提交点,如果权重都一样,Oracle随机选择提交点。

SYS@base> show parameter commit_point

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

commit_point_strength                integer     1

2PC(two phase commit)2阶段提交:第一阶段叫prepare phase准备阶段,第二阶段叫commit phase提交阶段。如果是本地事务就一阶段直接提交,如果是分布式事务就采取二阶段提交。下面解释一下这两个阶段的具体内容

Prepare phase 准备阶段

(1)每个节点检查自己是否被其他节点所引用,如果有就通知这些节点准备提交。

(2)每个节点检查自己运行的事务,看看有没有修改数据的操作,如果没有则跳过后面步骤直接返回一个只读信号给gc全局协调进程。

(3)如果事务需要修改数据,就分配相应的资源给事务并记录redo信息,这些redo信息保证事务失败后的回滚。

(4)当上面的工作都成功后,给gc全局协调进程返回准备就绪的信号,反之则返回失败的信号。

Commit phase 提交阶段

(1)首先gc全局协调器通知提交点进行提交,完成后告知gc。

(2)gc全局协调器再通知其他数据库节点进行提交并记录redo信息,完成后告知gc

(3)当gc得知所有分布式事务提交完成后,告知提交点数据库释放事务相关资源,完成后告知gc

(4)gc全局协调器释放自己的资源

(5)分布式事务结束

请分析分布式事务为什么无法保证事务最终的一致?请分析可能出现的问题以及解决方法。

这个论点已经由CAP理论证实了

CAP 理论断言任何基于网络的数据共享系统,最多只能满足数据一致性、高可用性、分区容错性三点中的两点。

CAP理论图示

AP架构实例:一个购物网站,如果允许系统实现高可用和分区容错性,当集群中某一节点出现故障的时候,就要暂时失去数据一致性,等待故障节点恢复正常,然后满足数据的最终一致性,允许经过一个时间窗口后在一致。

解决方法:对于事务性很强的关系型数据库而言,当发生一致性失败后,整个分布式事务都进行回滚,回退到初始状态,当故障解决后在运行事务操作。

我们在现实生活中常常会用“QQ传送文件”,当你发送一个文件传到一半的时候网络断了,这时就出现了数据不一致性现象,传送事务没有做完,通常QQ会选择放弃数据的一致性保证QQ程序可用性,等待网络恢复后继续完成事务。这里面QQ应用了上面提到的“保存点save point技术”实现断点续传功能,很好的解决了这个问题。

CA架构实例:中国人民银行的网上征信系统,必须满足一致性和高可用性,牺牲分区容错性,如果某个节点出现故障,断开网络连接,事务全部回退,暂停业务进行维修。

CP架构实例:某大学的图书馆系统,借还数据要保持一致,当有节点故障的时候,整个集群就会停止,维修后继续使用。

保存点自治事务分布式事务  CAP   数据一致性

转://Oracle 事务探索与实例(二)的更多相关文章

  1. 转://Oracle 事务探索与实例(一)

    一数据库版本 SYS@LEO1>select* from v$version; BANNER -------------------------------------------------- ...

  2. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  3. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  4. Oracle数据库基础入门《二》Oracle内存结构

    Oracle数据库基础入门<二>Oracle内存结构 Oracle 的内存由系统全局区(System Global Area,简称 SGA)和程序全局区(Program Global Ar ...

  5. 浅谈Oracle事务【转载竹沥半夏】

    浅谈Oracle事务[转载竹沥半夏] 所谓事务,他是一个操作序列,这些操作要么都执行,要么都不执行,是一个不可分割的工作单元.通俗解释就是事务是把很多事情当成一件事情来完成,也就是大家都在一条船上,要 ...

  6. Oracle事务之一:锁和隔离

    Oracle事务之一:锁和隔离 一. 事务概述 事务管理是数据库处理的核心.数据库既要保证用户能并发地执行事务,还要保证数据库的一致性. 当第一条可执行的SQL开始执行,就隐形地开始了一个事务,直到遇 ...

  7. oracle高级查询(实例基于scott用户四张表)

    oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ====================================================== ...

  8. Oracle EBS R12经验谈(二)

    作者: jianping.ni    时间: 2009-2-13 12:52     标题: Oracle EBS R12经验谈(二) OAF页面:银行帐户开户人LOV值列表无值    在输入 应付超 ...

  9. oracle 事务 与 提交

    Oracle事务 一般事务(DML)即数据修改(增.删.改)的事务事务会将所有在事务中被修改的数据行加上锁(行级锁),来阻止其它人(会话)同时对这些数据的修改操作.当事务被提交或回滚后,这些数据才会被 ...

随机推荐

  1. Mac下写博客工具ecto相关资料

    下载地址: https://www.macupdate.com/app/mac/8918/ecto 相关注册码: http://www.cnblogs.com/yssgyw/p/3284501.htm ...

  2. WPF实现主题更换的简单DEMO

    WPF实现主题更换的简单DEMO 实现主题更换功能主要是三个知识点: 动态资源 ( DynamicResource ) INotifyPropertyChanged 接口 界面元素与数据模型的绑定 ( ...

  3. Java io 入门

    目录 前言 代码演练 字符流 FileReader,FileWriter: BufferedReader,BufferedWriter: InputStreamReader,OutputStreamW ...

  4. 虚拟机与Docker有何不同?

    译者按: 各种虚拟机技术开启了云计算时代:而Docker,作为下一代虚拟化技术,正在改变我们开发.测试.部署应用的方式.那虚拟机与Docker究竟有何不同呢? 原文: Comparing Virtua ...

  5. input属性为number时,如何去掉+、-号?

    直接上答案 <style> input[type='number']{-moz-appearance:textfield;} input[type=number]::-webkit-inn ...

  6. Atom插件安装及推荐

    简介(了解更多去google或baidu) Atom 代码编辑器支持 Windows.Mac.Linux 三大桌面平台,完全免费,并且已经在 GitHub 上开放了全部的源代码.在经过一段长时间的迭代 ...

  7. JS单体内置对象之Math常用方法(min,max,ceil,floor,round,random等)

    1.min()和max()方法 Math.min()用于确定一组数值中的最小值.Math.max()用于确定一组数值中的最大值. alert(Math.min(2,4,3,6,3,8,0,1,3)); ...

  8. @meda媒体查询

    定义和使用 使用 @media 查询,你可以针对不同的媒体类型定义不同的样式. @media 可以针对不同的屏幕尺寸设置不同的样式,特别是如果你需要设置设计响应式的页面,@media 是非常有用的. ...

  9. Android Studio多渠道打包(二)

    虽然多渠道打包的方式有很多种,那么今天我要说的通过工具的形式进行多渠道打包 首先,打开Android studio,找到顶部Build,点开 选择红色部分,里面的编辑框可以帮助我们更快的熟悉Gradl ...

  10. 编程经验点滴----巧妙解决 Oracle NClob 读写问题

    最近一个新项目中,尝试在 Oracle 数据库中使用 NCLOB 来保存大的 xml 字符串. 在代码自动生成工具(通过 JDBC 驱动程序,读数据库表结构,自动生成对应的 java 代码,包含增加. ...