关于SET TRANSACTION READ ONLY

DATEBASE — 作者 kiswind @ 14:52

[ZT]ORACLE的隔离级别

隔离级别(isolation level)

l 隔离级别定义了事务与事务之间的隔离程度。

l 隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。

l ANSI/ISO SQL92标准定义了一些数据库操作的隔离级别:

l 未提交读(read uncommitted)

l 提交读(read committed)

l 重复读(repeatable read)

l 序列化(serializable)

l 通过一些现象,可以反映出隔离级别的效果。这些现象有:

l 更新丢失(lost update):当系统允许两个事务同时更新同一数据是,发生更新丢失。

l 脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。

l 非重复读(nonrepeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。(A transaction rereads data it has previously read and finds that another committed transaction has modified or deleted the data. )

l 幻像(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。(A transaction reexecutes a query returning a set of rows that satisfies a search condition and finds that another committed transaction has inserted additional rows that satisfy the condition. )

l 下面是隔离级别及其对应的可能出现或不可能出现的现象

Dirty Read

NonRepeatable Read

Phantom Read

Read uncommitted

Possible

Possible

Possible

Read committed

Not possible

Possible

Possible

Repeatable read

Not possible

Not possible

Possible

Serializable

Not possible

Not possible

Not possible

ORACLE的隔离级别

l ORACLE提供了SQL92标准中的read committed和serializable,同时提供了非SQL92标准的read-only。

l read committed:

l 这是ORACLE缺省的事务隔离级别。

l 事务中的每一条语句都遵从语句级的读一致性。

l 保证不会脏读;但可能出现非重复读和幻像。

l serializable:

l 简单地说,serializable就是使事务看起来象是一个接着一个地顺序地执行。

l 仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。

l 保证不会出现非重复读和幻像。

l Serializable隔离级别提供了read-only事务所提供的读一致性(事务级的读一致性),同时又允许DML操作。

l 如果有在serializable事务开始时未提交的事务在serializable事务结束之前修改了serializable事务将要修改的行并进行了提交,则serializable事务不会读到这些变更,因此发生无法序列化访问的错误。(换一种解释方法:只要在serializable事务开始到结束之间有其他事务对serializable事务要修改的东西进行了修改并提交了修改,则发生无法序列化访问的错误。)

l If a serializable transaction contains data manipulation language (DML) that attempts to update any resource that may have been updated in a transaction uncommitted at the start of the serializable transaction, (并且修改在后来被提交而没有回滚),then the DML statement fails. 返回的错误是ORA-08177: Cannot serialize access for this transaction。

l ORACLE在数据块中记录最近对数据行执行修改操作的N个事务的信息,目的是确定是否有在本事务开始时未提交的事务修改了本事务将要修改的行。具体见英文:Oracle permits a serializable transaction to modify a data row only if it can determine that prior changes to the row were made by transactions that had committed when the serializable transaction began. To make this determination efficiently, Oracle uses control information stored in the data block that indicates which rows in the block contain committed and uncommitted changes. In a sense, the block contains a recent history of transactions that affected each row in the block. The amount of history that is retained is controlled by the INITRANS parameter of CREATE TABLE and ALTER TABLE. Under some circumstances, Oracle may have insufficient history information to determine whether a row has been updated by a "too recent" transaction. This can occur when many transactions concurrently modify the same data block, or do so in a very short period. You can avoid this situation by setting higher values of INITRANS for tables that will experience many transactions updating the same blocks. Doing so will enable Oracle to allocate sufficient storage in each block to record the history of recent transactions that accessed the block.

l The INITRANS Parameter:Oracle stores control information in each data block to manage access by concurrent transactions. Therefore, if you set the transaction isolation level to serializable, you must use the ALTER TABLE command to set INITRANS to at least 3. This parameter will cause Oracle to allocate sufficient storage in each block to record the history of recent transactions that accessed the block. Higher values should be used for tables that will undergo many transactions updating the same blocks.

l read-only:

l 遵从事务级的读一致性,仅仅能看见在本事务开始前由其它事务提交的更改。

l 不允许在本事务中进行DML操作。

l read only是serializable的子集。它们都避免了非重复读和幻像。区别是在read only中是只读;而在serializable中可以进行DML操作。

l Export with CONSISTENT = Y sets the transaction to read-only.

l read committed和serializable的区别和联系:

l 事务1先于事务2开始,并保持未提交状态。事务2想要修改正被事务1修改的行。事务2等待。如果事务1回滚,则事务2(不论是read committed还是serializable方式)进行它想要做的修改。如果事务1提交,则当事务2是read committed方式时,进行它想要做的修改;当事务2是serializable方式时,失败并报错“Cannot serialize access”,因为事务2看不见事务1提交的修改,且事务2想在事务一修改的基础上再做修改。具体见英文:Both read committed and serializable transactions use row-level locking, and both will wait if they try to change a row updated by an uncommitted concurrent transaction. The second transaction that tries to update a given row waits for the other transaction to commit or roll back and release its lock. If that other transaction rolls back, the waiting transaction (regardless of its isolation mode) can proceed to change the previously locked row, as if the other transaction had not existed. However, if the other (blocking) transaction commits and releases its locks, a read committed transaction proceeds with its intended update. A serializable transaction, however, fails with the error "Cannot serialize access", because the other transaction has committed a change that was made since the serializable transaction began.

l read committed和serializable可以在ORACLE并行服务器中使用。

l 关于SET TRANSACTION READ WRITE:read write和read committed 应该是一样的。在读方面,它们都避免了脏读,但都无法实现重复读。虽然没有文档说明read write在写方面与read committed一致,但显然它在写的时候会加排他锁以避免更新丢失。在加锁的过程中,如果遇到待锁定资源无法锁定,应该是等待而不是放弃。这与read committed一致。

l 语句级的读一致性

l ORACLE保证语句级的读一致性,即一个语句所处理的数据集是在单一时间点上的数据集,这个时间点是这个语句开始的时间。

l 一个语句看不见在它开始执行后提交的修改。

l 对于DML语句,它看不见由自己所做的修改,即DML语句看见的是它本身开始执行以前存在的数据。

l 事务级的读一致性

l 事务级的读一致性保证了可重复读,并保证不会出现幻像。

l 设置隔离级别

l 设置一个事务的隔离级别

l SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

l SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

l SET TRANSACTION READ ONLY;

l 设置增个会话的隔离级别

l ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;

l ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;

http://blog.oracle.com.cn/185365/viewspace_4805.html

一致性和事务
  一致性是事物控制的关键慨念。掌握了oracle 的一致性模型,能使您更好的,更恰当的使用事务控制。oracle通过一致性保证数据只有在事务全部完成后才能被用户看见和使用。这项技术对多用户数据库有巨大的作用。
  oracle常常使用语句级(state-level)一致性,保证数据在语句的生命期之间是可见的但不能被改变。事务由多个语句组成,当使用事务时,事物级(transaction-level)一致性在整个事务生命期中保证数据对所有语句都是可见的。
  oracle通过SCN(syatem change number)实施一致性。一个SCN是一个面向时间的数据库内部键。SCN只会增加不会减少,SCN表示了时间上的一个点,每个数据块都有一个SCN,通过比较这个点实施操作。
  事务级一致性
  SET TRANSACTION 的一个作用是确保事务级一致或语句级一致中有一个实施。ORACLE使用这些术语:
   ISOLATION LEVEL READ COMMIT 表示语句级一致
   ISOLATION LEVEL SERIALIZABLE 表示事务级一致。
  例:

SET TRANSACTION ISOLATION LEVEL READ COMMIT;

SET TRANSACTION ISOLATION LEVEL READ COMMIT
  下面的语句也能确保事务级一致:

SET TRANSCATION READ ONLY
  任何企图在只读(READ ONLY)事务中修改数据的操作都会抛出一个异常。但是,READ ONLY事务只能在下列语句中使用:

SELECT(没有FOR UPDATE子句)
LOCK TABLE
SET ROLE
ALTER SYSTEM
ALTER ALARM
  即使没有改变任何数据,READ ONLY事务依然必须使用一个COMMIT或ROLLBACK以结束整个事务。

http://www.itpub.net/showthread.php?threadid=313083&pagenumber

http://www.itpub.net/500115.html

http://skygodblue.spaces.live.com/Blog/cns!D18CEE1DB3D21A07!464.entry

Transactions and Data Concurrency

折腾了一下午,弄个isolation level,好歹也要写点东西出来,要不然就白忙活这一个下午了。

其实所谓的 隔离级别只不过是 事务与事务之间的隔离程度

oracle提供了三种隔离级别 read committed (default)和serializable以及 非SQL92标准的read-only.

read commited:

从字面意思可以理解为不脏读,也就是说某一transaction只能读取其它trasaction的已经commit的数据和本transaction的没有提交的数据,也就是我们所理解的读一致性。

serializable:

这个就不是从字面意思理解的那样了。

它仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。也就是说,其一旦设置了serializable的隔离级别之后,不管其它的会话的数据如何发生改变(不管是commit,还是不comit),并不影响本transaction 所能读取到的数据。也就是说,一旦设置了serializable的隔离级别之后,本transaction所能读取到的其它transaction的数据就是已经是固定的了,保证不会出现非重复读和幻像。

同时 serializable隔离级别允许DML操作,这是它与read only级别最大的不同之处。

tom 的解释:

A SERIALIZABLE transaction operates in an environment that makes it appear as if there are no other users modifying data in the database, the database will be ‘frozen’ at the point in time your query began. Your transaction sees the database consistently, at a single point in time. Side effects (changes) made by other transactions are not visible to it, regardless of how long it has been running. SERIALIZABLE does not mean that all transactions executed by the users are the same as if they were executed one right after another in a serial fashion. It does not imply that there is some serial ordering of the transactions that would result in the same outcome.

In Oracle, serializability is achieved by extending the read consistency we get at the statement level to the transaction level. Instead of results being consistent with respect to the start of a statement, they are pre-ordained at the time you begin the transaction.(也就是说,serializability级别下获得的数据是 会话开始时的时候 所能读取的数据,而并不是查询表达式发出时所能读取的数据) Pretty deep thought there – the database already knows the answer to any question you might ask it, before you ask it.

read only:

read only是serializable的子集。它们都避免了非重复读和幻像。区别是在read only中是只读;而在serializable中可以进行DML操作。

下面是关于serializable 两种设置隔离级别的实验:

session 1:

SQL> conn kingping
已连接。
SQL> desc b
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
X NUMBER
SQL> set time on
18:08:40 SQL>
18:09:29 SQL>
18:09:29 SQL> insert into b values(1);
已创建 1 行。
18:10:21 SQL> commit;
提交完成。
18:10:23 SQL> update b set x = 2 where x = 1;
已更新 1 行。
18:10:41 SQL> commit;
提交完成。
18:10:43 SQL> delete from b;
已删除 1 行。
18:10:52 SQL> commit;
提交完成。
18:10:54 SQL>
18:12:10 SQL>
18:12:11 SQL> insert into b values(1);
已创建 1 行。
18:12:13 SQL> commit;
提交完成。
18:12:14 SQL> update b set x = 2 where x = 1;
已更新 1 行。
18:12:19 SQL> commit;
提交完成。
18:12:20 SQL> delete from b;
已删除 1 行。
18:12:25 SQL> commit;
提交完成。

session 2:

在Session级别设置:

SQL> conn kingping
已连接。
SQL> set time on
18:09:17 SQL>
18:09:45 SQL>
18:09:45 SQL> Alter session set isolation_level=serializable;
会话已更改。
18:10:12 SQL> select * from b;
未选定行
18:10:17 SQL>
18:10:25 SQL> select * from b;
未选定行
18:10:25 SQL> select * from b;
未选定行
18:10:45 SQL> select * from b;
未选定行

在transaction级别设置:

SQL> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
事务处理集。
SQL> select * from b;
未选定行
SQL> select * from b;
未选定行
SQL> select * from b;
未选定行
SQL> select * from b;
未选定行

关于read committed和 serializable之间的区别以及 ORA-08177错误:

If a serializable transaction contains data manipulation language (DML) that attempts to update any resource that may have been updated in a transaction uncommitted at the start of the serializable transaction, (并且修改在后来被提交而没有回滚),then the DML statement fails. 返回的错误是ORA-08177: Cannot serialize access for this transaction。

事务1先于事务2开始,并保持未提交状态。事务2想要修改正被事务1修改的行。事务2等待。如果事务1回滚,则事务2(不论是read committed还是serializable方式)进行它想要做的修改。如果事务1提交,则当事务2是read committed方式时,进行它想要做的修改;当事务2是serializable方式时,失败并报错“Cannot serialize access”,因为事务2看不见事务1提交的修改,且事务2想在事务一修改的基础上再做修改.

具体见document:Both read committed and serializable transactions use row-level locking, and both will wait if they try to change a row updated by an uncommitted concurrent transaction. The second transaction that tries to update a given row waits for the other transaction to commit or roll back and release its lock. If that other transaction rolls back, the waiting transaction (regardless of its isolation mode) can proceed to change the previously locked row, as if the other transaction had not existed. However, if the other (blocking) transaction commits and releases its locks, a read committed transaction proceeds with its intended update. A serializable transaction, however, fails with the error "Cannot serialize access", because the other transaction has committed a change that was made since the serializable transaction began.

session1:

19:17:06 SQL> set time on
19:17:07 SQL> insert into b values(1);
已创建 1 行。
19:17:14 SQL> commit;
提交完成。19:17:15 SQL> select * from b;

X
----------
1
19:17:17 SQL> update b set x=2 where x=1;
已更新 1 行。

19:18:19 SQL> commit;提交完成。
19:18:21 SQL> update b set x=3 where x=2;
已更新 1 行。

19:18:43 SQL>
19:19:21 SQL> rollback;回退已完成。

session2:

19:17:29 SQL> select * from b;

X
----------
1
19:17:36 SQL> Alter session set isolation_level=serializable;
会话已更改。
19:17:38 SQL> update b set x = 2 where x =1; (假如session1不commit,则此处hang)update b set x = 2 where x =1
*
ERROR 位于第 1 行:
ORA-08177: 无法连续访问此事务处理 (session1 commit)19:18:21 SQL> select * from b;

X
----------
2 (但是此处竟然可以看到session1更改的结果,不明白原因)
19:18:32 SQL> update b set x = 4 where x =2; (假如session1不commit,则此处hang)
已更新 1 行。 (session1 rollback)

read committed下的实验就不做了。

另外还有一点比较奇怪:

http://asktom.oracle.com/pls/ask/f?p=4950:8:15112311275040223112::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:7636765105002

数据库隔离级别(收藏)相关推荐

  1. Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据库隔离级别

    Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据库隔离级别 AOP:面向切面编程. 即在一个功能模块中新增其他功能,比方说你要下楼取个快递,你同事对你说 ...

  2. Spring事务管理amp;数据库隔离级别

    一.spring事务管理 1. 什么是事务 事务(Transaction)是多个操作数据库的步骤(CRUD)的集合,是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可 ...

  3. mysql ansi sql标准_Mysql数据库隔离级别(ANSI SQL92规范,行锁,间隙锁)

    一. 什么是数据库隔离级别? ANSI(美国国家标准学会:AMERICAN NATIONAL STANDARDS INSTITUTE)在多个事务并发的时候能够正确的处理数据所定义的规范.事务隔离级别越 ...

  4. 数据库隔离级别发展史

    数据库隔离级别发展史 前言 ANSI SQL标准(1992):基于异象 A Critique of ANSI(1995):基于锁 问题本质 A Generalized Theory(1999):基于序 ...

  5. tidb数据库隔离级别剖析

    本文章来源于:https://github.com/Zeb-D/my-review ,请star 强力支持,你的支持,就是我的动力. [TOC] 前言 在线应用业务中,数据库是一个非常重要的组成部分, ...

  6. Spring事务隔离级别与数据库隔离级别不一致时,该以谁为准?

    原创博文,欢迎转载,转载时请务必附上博文链接,感谢您的尊重. 前言 通过本篇,你将了解到[Spring事务]与[数据库事务]的关系,以及优先级问题,我将为你一一论证. 阅读本篇,你可能会需要的博文: ...

  7. 数据库隔离级别与实践

    数据库隔离级别 1:读未提交 - 一个Connection读取到了别的连接还没有提交的数据.Read uncommitted. 2:读已提交 - Read COMMITTED 3:可重复读 - Rep ...

  8. 哪种数据库隔离级别能防止脏读?(多选题)

    32.哪种数据库隔离级别能防止脏读?(多选题) A. Read committed B. Read uncommitted C. Serializable D. Repeatable read 正确答 ...

  9. 数据库隔离级别 及 其实现原理

    1.脏读 脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据. 2.不可重复读 不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一 ...

  10. 数据库隔离级别实现原理

    昨晚和以为前辈聊天,聊到Mysql的引擎innodb默认的事务隔离级别是REPEATABLE READ(可重复读):在Oracle中默认的事务隔离级别是提交读(read committed).那么,问 ...

最新文章

  1. 浙江大学软件学院2020年保研上机模拟练习 7-2 Distance of Triples
  2. 3d大爱心c语言程序,C语言控制台打印3D爱心图案
  3. DirectX 9的坐标系统变换
  4. Python零碎知识(1):strip lstrip rstrip使用方法
  5. Java中ClassLoader浅析.
  6. 1067 Sort with Swap(0, i) (25 分)【难度: 中 / 知识点: 置换群】
  7. 【小白学习C++ 教程】二、C++基础语法、注释和变量
  8. java的创建管理员对象_java--更改管理员密码,请列位帮忙看看有没有更好的实现方式...
  9. HackerOne 发布2021年《黑客驱动安全报告:行业洞察》
  10. pycharm怎么做html网页_html下拉菜单怎么做
  11. idea配置Tomcat乱码处理
  12. phpQuery占用过多内存的解决方法
  13. socks5协议(rfc1928)
  14. HtmlUnit实现人人网登陆
  15. 8类网线利弊_浅析网线8芯线各自的作用
  16. [安洵杯 2019]easy misc 1
  17. 基于复化辛卜生求积公式的变步长求积算法
  18. Kali linux最新2018年安装Netspeed
  19. 原来陪伴夜的不只有路灯啊
  20. 封神台靶场(一)为了女神小芳 【SQL注入攻击】(超级详细)

热门文章

  1. Android期末作品
  2. 网络监听的防护(电脑篇)
  3. 世界各国(地区)LCID信息列表
  4. 优达学城无人驾驶工程师——P1寻找车道线
  5. 1109 擅长C – PAT乙级真题
  6. 【毕业设计/Matlab系列】基于PCA和BP神经网络的人脸识别系统(基于AR人脸库)
  7. android新建txt文件类型,Android开发:新建后缀为txt的文件并且使用的步骤
  8. 西门子s7 200smart与台达伺服电机 运动控制的学习,目标:用触摸屏和西门子smart 控制
  9. safari下载文件自动追加exe后缀解决方法
  10. 如何自己编译wireless tool