Oracle事务Transaction

2020-09-18  本文已影响0人  职场亮哥

参考资料:

<a href="https://docs.oracle.com/cd/E11882_01/server.112/e40540/transact.htmhttps://docs.oracle.com/cd/E11882_01/server.112/e40540/transact.htm" rel="nofollow">Transactions</a>

关于Oracle事务的总结


什么是事务?

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

事务的属性-ACID

数据库事务的开始和结束

以第一个DML语句的执行作为开始

以下面的其中之一作为结束:

并发与数据的读取

当多个会话同时访问(操作)相同的数据时,将会出现一些意想不到的结果。包括:

事务的隔离等级

ANSI定义的事务的隔离等级:

事务隔离等级 脏读 不可重复读 幻读
Read uncommited(读未提交的) Y Y Y
Read commited(读提交的) N Y Y
Repeatable read N N Y
Serializable N N N

Oracle定义的事务隔离等级:

事务隔离等级 影响
Read commited Oracle默认的隔离等级,对一条SQL,可以保证数据的一致性,对于一个事务,无法做到repeatable read。
Serializable 只能看到事务开始时所有提交的改变以及自身的改变
Read-only 只能看到事务开始时所有提交的改变,自身不允许DML操作

事务的并发控制-锁

Oracle的锁定机制

Oracle和Sql Server锁的区别

Sql Server Oracle
并发和读一致性不可兼得,必须牺牲一方 可兼得
因为锁实现方式,事务代价昂贵 没有真正的锁,事务没有资源代价
提倡尽快提交 主张按照业务需求确定事务边界

事务的控制-savepoint

通过在事务中间设置检查点,可以更加精细的控制事务,防止一部分错误操作导致整个事务重新运行。演示如下:

SQL> create table t(id int);

表已创建。

SQL> insert into t values(1);

已创建 1 行。

SQL> savepoint s1;

保存点已创建。

SQL> select * from t;

        ID
----------
         1

SQL> update t set id=2;

已更新 1 行。

SQL> savepoint s2;

保存点已创建。

SQL> select * from t;

        ID
----------
         2

SQL> rollback to s1;

回退已完成。

SQL> select * from t;

        ID
----------
         1

一旦返回到保存点s1之后s2就失去了效果,因为已经回到s1了,这时候s2还不存在。

自治事务

自治事务允许在一个事务中存在独立的事务,它的操作不会对当前事务产生影响。

语法:

pragma autonomous_transaction

关于自治事务的使用可以参考:ORACLE中的自治事务

实验演示如下:(演示用例来自参考资料Oracle中的自治事务)

首先是不使用自治事务

SQL> create table msg (msg varchar2(120));
SQL> set serveroutput on
SQL> declare
  2    cnt number := -1;  --} Global variables
  3    procedure local is
  4    begin
  5       select count(*) into cnt from msg;
  6       dbms_output.put_line('local: # of rows is '||cnt);
  7
  8       insert into msg values ('New Record');
  9       commit;
 10    end;
 11    begin
 12       delete from msg ;
 13       commit;
 14       insert into msg values ('Row 1');
 15       local;
 16       select count(*) into cnt from msg;
 17       dbms_output.put_line('main: # of rows is '||cnt);
 18       rollback;
 19
 20       local;
 21       insert into msg values ('Row 2');
 22       commit;
 23
 24       local;
 25       select count(*) into cnt from msg;
 26       dbms_output.put_line('main: # of rows is '||cnt);
 27    end;
 28  /
local: # of rows is 1  -> 子程序local中可以’看到’主匿名块中的uncommitted记录
main: # of rows is 2   -> 主匿名块可以’看到’2条记录(它们都是被local commit掉的)
local: # of rows is 2  -> 子程序local首先’看到’2条记录,然后又commit了第三条记录
local: # of rows is 4  -> 子程序local又’看到’了新增加的记录(它们都是被local commit掉的),然后又commit了第五条记录
main: # of rows is 5   -> 主匿名块最后’看到’了所有的记录. 

PL/SQL 过程已成功完成。

从这个例子中,我们看到COMMIT和ROLLBACK的位置无论是在主匿名块中或者在子程序中,都会影响到整个当前事务.

现在如果将procedure local改成自治事务,在procedure local后面加上:

pragma AUTONOMOUS_TRANSACTION;

效果如下:

SQL> declare
  2    cnt number := -1;  --} Global variables
  3    procedure local is
  4    pragma AUTONOMOUS_TRANSACTION;
  5    begin
  6       select count(*) into cnt from msg;
  7       dbms_output.put_line('local: # of rows is '||cnt);
  8
  9       insert into msg values ('New Record');
 10       commit;
 11    end;
 12    begin
 13       delete from msg ;
 14       commit;
 15       insert into msg values ('Row 1');
 16       local;
 17       select count(*) into cnt from msg;
 18       dbms_output.put_line('main: # of rows is '||cnt);
 19       rollback;
 20
 21       local;
 22       insert into msg values ('Row 2');
 23       commit;
 24
 25       local;
 26       select count(*) into cnt from msg;
 27       dbms_output.put_line('main: # of rows is '||cnt);
 28    end;
 29  /
local: # of rows is 0  -> 子程序local中无法可以’看到’主匿名块中的uncommitted记录 (因为它是独立的)
main: # of rows is 2   -> 主匿名块可以’看到’2条记录,但只有一条是被commited.
local: # of rows is 1  -> 子程序local中可以’看到’它前一次commit的记录,但是主匿名块中的记录已经被提前rollback了
local: # of rows is 3  -> 子程序local 中可以’看到’3条记录包括主匿名块commit的记录
main: # of rows is 4   ->主匿名块最后’看到’了所有的记录.

PL/SQL 过程已成功完成。

分布式事务

分布式事务的组成

角色 描述
client 调用其它数据库信息的节点
database 接受来自其它节点请求的节点
Global coordinate 发起分布式事务的节点(全局调度者)
Local coordinate 处理本地事务,并和其它节点通信的节点(本地调度者)
Commit point site 被global coordinate指定第一个提交或回滚事务的节点

commit Point Strength

Oracle选取Commit Point Strength(相当于权重)最大的数据库作为Commit point。

Oracle分布式事务的机制-两阶段提交

2PC-two phase commit

准备阶段prepare phase

为了完成准备阶段,除了commit point机器外,其它的数据库机器按照以下步骤执行:

提交阶段commit phase

提交阶段按下面的步骤进行:

分布式事务的结束

分布式事务的结束就是全局协调器和commit point两者之间释放资源的顺序。

分布式事务的安全性

2PC是否真的可以保证分布式事务的一致性?

关于CAP理论可以参见:CAP理论


念念不忘,必有回响,小伙伴们帮我点个赞吧,非常感谢。

我是职场亮哥,YY高级软件工程师、四年工作经验,拒绝咸鱼争当龙头的斜杠程序员。

听我说,进步多,程序人生一把梭

如果有幸能帮到你,请帮我点个【赞】,给个关注,如果能顺带评论给个鼓励,将不胜感激。

职场亮哥文章列表:更多文章

本人所有文章、回答都与版权保护平台有合作,著作权归职场亮哥所有,未经授权,转载必究!

上一篇 下一篇

猜你喜欢

热点阅读