热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Oracle事务特征管理读取详解

本文章总结了关于Oracle事务介绍了事务特征事务管理事务读三种用法与举实例说明,有需要了解的朋友可以参考一下本文章。

本文章总结了关于Oracle事务介绍了事务特征 事务管理 事务读三种用法与举实例说明,有需要了解的朋友可以参考一下本文章。

本文章总结了关于Oracle事务介绍了事务特征 事务管理 事务读三种用法与举实例说明,有需要了解的朋友可以参考一下本文章。

Oracle 事务的特征
ACID,指事务正确执行的四个基本要素的缩写.包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。一个支持交易(Transaction)的数据库系统,必需要具有这四种特性,否则在交易过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求.
原子性 (ATOMICITY)

整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性 (CONSISTENCY)

在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

隔离性 (ISOLATION)

两个事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。

持久性 (DURABILITY)

在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。


oracle中通常情况下有三种读:

第一种:错读(未提交读),就是读到另一个事物修改过的但没有提交的数据,没有实一致性读。

第二种:不可重复读( 读失真)就是对一个事物前后两次读,读出来的值是不相等的,因为它在这两次读的间隔被别的事物修改或者删除,并且提交了。

第三种读:幻想读 某个事务在两次读之间,有另一事务插入新的数据,并提交,而且插入的数据满足查询的条件,导致读到的数据不一样。

oracle读一致性又分为:

1.语句级读一致性(不可重复读)

2.事务级一致性读

语句性一致性读,比如语句在开始执行之前获得当前的scn号为10001,而另个事务T2可能将该块的行进行修改,设置该行所在块的一致性标记,生成的SCN=10002,这种情况就需要应用undo回滚到scn为10001的时刻,即为一致性状态,在单个语句执行期间这个值是不会改变的。

事务级别一致性读,所有数据的状态是在事务起始的状态,除非本事务修改的数据,这样就可以避免了不可重复读和幻想读。

oracle是通过隔离级来实现事务的一致性读,事务级可以通过回滚段能实现一致性读,虽然别人可能修改了,但是可以利用回滚段,把别人修改的给回滚了。

事务级一致性读就得说道串行读所谓串行读就是你一人在读的话,别人修改不影响你读的结果,可以无视别人的修改。虽然对于数据库是生效了,但是对于串行事务,则被无视。

串行读适合用在下面三种情况:

a.大型数据库中大多是小数据集的DML短事务

b.修改同一行的几率非常低的系统.

c.长运行事务主要是只读的系统

这块主要是从回滚段来考虑的,应为串行读是通过回滚段来实现的。

设置隔离级命令

代码如下

1.SET TRANSACTION ISOLATION LEVEL READ COMMITTED;(提交度隔离级)
2.SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; (串行读隔离级)
3.SET TRANSACTION ISOLATION LEVEL READ ONLY;(只读隔离级)

还有一种设置

代码如下

ALTER SESSION
ALTER SESSION SET ISOLATION_LEVEL=SERIALIZABLE;
ALTER SESSION SET ISOLATION_LEVEL=READ COMMITTED

下面来举一个串行隔离的例子,代码如下

代码如下
SQL> create table t ( x int );
Table created
SQL> insert into t values ( 1 );
1 row inserted
SQL> commit;
Commit complete
SQL> set transaction isolation level serializable;
Transaction set
SQL> * from t;
X
---------------------------------------
1
SQL>
SQL> declare
2 pragma autonomous_transaction;
3 begin
4 delete from t;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed
SQL> select * from t;

X
---------------------------------------
1
SQL> commit;
Commit complete
SQL> select * from t;
X

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

中间用到的是自制事务,相当于重新启动了一个事务,通过例子可以看出,虽然删除了,但是第一个事务仍然可以看到,这块其实在数据库中已经修改了,只是通过回滚段可以看到,最后一提交,再查看,就会发现真正的删除了。

我们开始试验一,模拟语句级别读一致性。第一个session使用显示打开一个游标模拟数据读,同时在游标读数据的过程中,启动另外一个session更改数据,我可以看到另外一个session对数据的更改,并不会改变到第一个session的读。这就是语句级别的读一致性。

启动一个session连接数据库:

代码如下
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as cbo

SQL> set serveroutput on;
SQL>
SQL> create table test(id number,name varchar2(10));

Table created
SQL> insert into test values(1,'a');

1 row inserted
SQL> insert into test values(2,'b');

1 row inserted
SQL> commit;

Commit complete

SQL>
SQL> declare
2 cursor cur is select * from test;
3 begin
4 for rec in cur
5 loop
6 dbms_output.put_line(rec.name);
7 dbms_lock.sleep(10);--中间等待另外一个session启动并执行更新数据操作
8 end loop;
9 end;
10 /

a
b

PL/SQL procedure successfully completed

SQL>

在执行游标打印输出的时候同时启动另外一个进程,执行更新数据操作:

代码如下

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as cbo

SQL> set serveroutput on;
SQL>
SQL> create table test(id number,name varchar2(10));

Table created
SQL> insert into test values(1,'a');

1 row inserted
SQL> insert into test values(2,'b');

1 row inserted
SQL> commit;

Commit complete

SQL>
SQL> declare
2 cursor cur is select * from test;
3 begin
4 for rec in cur
5 loop
6 dbms_output.put_line(rec.name);
7 dbms_lock.sleep(10);
8 end loop;
9 end;
10 /

a
b

PL/SQL procedure successfully completed

SQL>

下面我们开始试验二,模拟事务级别读一致性。
首先启动一个SESSION,读一次数据:

代码如下

SQL> SET TRANSACTION READ ONLY;

Transaction set

SQL> select * from test;

ID NAME
---------- ----------
1 a
2 bbbb

接下来我们启动另外一个session,执行更新数据操作:

代码如下

SQL> update test set name='123456';

2 rows updated

SQL> commit;

Commit complete

最后我们回到第一session查看再次查看数据:

代码如下

SQL> select * from test;

ID NAME
---------- ----------
1 a
2 bbbb

我们会发现读出的数据并没有发生改变。所以在设置了SET TRANSACTION READ ONLY后,一个事务前后语句读取的数据不会因为其他seesion对数据的更新而改变。


Oracle事务管理

一个事务包含一个或多个SQL语句,是逻辑管理的工作单元(原子单元)。
一个事务开始于第一次执行的SQL语句,结束于Commit 或 Rollback 或 DDL语句。
注意:其中Commit, Rollback是显示的提交事务,而DDL语句是隐式的提交事务的。DDL语句的操作是

没有办法回滚的。
##########################

代码如下

eg:
SQL> create table a ( i int);

表已创建。

SQL> insert into a values(1);

已创建 1 行。

SQL> create table b ( i int);

表已创建。

SQL> rollback;

回退已完成。

SQL> select * from a;

I
----------
1

#############################
在执行create table b 的时候事务就已经提交了。
事务结束的地方有:
1>. 执行Commit, Rollback, 没有使用savepoint.
2>. 执行DDL操作如:create , drop, rename, alter
3>. 断开与Oracle的连接,事务将自动提交。
4>. 用户进程异常终止,当前事务回滚。

注意:应用程序与Oracle连接的情况,在应用程序终止前必须显示的提交(Commit)或回滚(Rollback)。

Commit操作Oracle做了:
1>. 与UNDO表空间关联的内部事务表记录该事务已经提交,产生唯一的系统交易号(SCN)保存到该表

中。
2>. LGWR进程将SGA中的重做日志写入redo log文件,当然也要写SCN到重做日志文件。
3>. Oracle释放锁定表中的行。
4>. Oracle设置该事务完成。

注意:Commit操作前的改变数据(保存在SGA)不会马上写到数据文件中。这样做的目的也是为了数据

库更高效。从开发人员的角度想想也是这样的,这样可以减少很多小事务的多次写磁盘的。

Oracle 10.2中与事务有关的:

代码如下
commit work write immediate wait; --是Oracle默认的设置。
alter system set commit_write = nowait; --改变系统提交方式
alter session set commit_write = nowait; --改变会话提交方式

##############################
提交一个事务 eg:

代码如下
SQL> commit work;

提交完成。

代码如下

SQL> show autocommit;
autocommit OFF
SQL> create table t0(testcol number);

表已创建。

代码如下

SQL> insert into t0 values(1);

已创建 1 行。

SQL> commit;

提交完成。

代码如下

SQL> select * from t0;

TESTCOL
----------
1

SQL> insert into t0 values(2);

已创建 1 行。

SQL> commit work;

提交完成。

代码如下

SQL> select * from t0;

TESTCOL
----------
1
2

####################################
commit comment eg:


推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 推荐一个ASP的内容管理框架(ASP Nuke)的优势和适用场景
    本文推荐了一个ASP的内容管理框架ASP Nuke,并介绍了其主要功能和特点。ASP Nuke支持文章新闻管理、投票、论坛等主要内容,并可以自定义模块。最新版本为0.8,虽然目前仍处于Alpha状态,但作者表示会继续更新完善。文章还分析了使用ASP的原因,包括ASP相对较小、易于部署和较简单等优势,适用于建立门户、网站的组织和小公司等场景。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
author-avatar
淅沥的雨的海角_960
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有