oracle如何支持幻读 oracle只读表可以执行哪些命令

1.3 REPEATABLE READ(可重复读)1.设置为可重复读
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
2.首先TB做出一次查询,此时name为bb
3.TA对数据进行修改 , 并提交
4.此时加入session C作为对比,使用自动事务并做出查询,可见数据已经被修改
5.在已经开启事务的TB中,查询到的,仍然是数据开启事务之前的状态,所以数据是可重复读的
可重复读隔离级别中 , 每当事务开始后,第一次执行sql语句时(或者执行START TRANSACTION WITH CONSISTENT SNAPSHOT)MVCC会建立一个read view,选取当时的系统版本号,作为事务版本号,以Undo log的行系统版本号与事务版本号进行对比 , 增删改查都要遵循如下模式:
SELECT:
1, InnoDB只查找版本早于当前事务版本的数据行(行的系统版本号小于等于事务版本号),这样可以确保事务读取的行,要么是事务开始前就存在的,要么是事务自身插入的或修改过的 。
2, 行的删除号要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行,在事务开始之前未被删除 。
INSERT:
InnoDB 为新插入的每一行保存当前系统版本号做为行版本号 。
DELETE:
INNODB 为删除的每一行保存当前系统版本号作为行删除标识 。
UPDATE:
InnoDB 为插入的每一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识 。
所以READ COMMITTED和REPEATABLE READ的区别在于,READ COMMITTED总是读取被锁定行的最新一份快照数据,所以会有不可重复读的问题 。而REPEATABLE READ读取事务开始时行系统版本号小于事务版本号的数据,解决不可重复读的问题 。
此外要提的一点是 , MySql的REPEATABLE READ与Oracle的不同 , 不但解决了不可重复读问题,还解决的“幻读”问题 。
幻读的产生:遵循上述增删改查模式,假设TA事务的事物版本号为3,TB早于TA开启事务,TB事物版本号为2,TB先新增一条数据,行数据的版本号为2,并提交 。TB提交后,TA查询时 , 满足“行的系统版本号小于等于事务版本号”的条件,可以查到数据,形成“幻读” 。
InnoDB采用Next-key Lock(间隙锁)来避免“幻读”问题 。
Record Lock:单个行记录的锁,锁定的是索引而非记录本身 。
GAP Lock:间隙锁,锁定一个范围,但不包含记录本身 。
Next-Key Lock:Gap Lock Record Lock 锁定一个范围并锁定记录本身 。
举例说明:
某表字段为ID和NAME , 有3条睡觉 , ID分别为10 , 20,50 。
如果索引为 10,20,50 , 那么:
Record Lock:select * from tab where id = 10 for update; //对id=10单行进行加锁
Gap Lock锁范围:(-∞,10)(10,20)(20 , 50)(50, ∞)
Next-Key Lock锁范围:(-∞,10] (10,20] (20,50] (50,∞)
【oracle如何支持幻读 oracle只读表可以执行哪些命令】 当查询的索引含有唯一属性时,InnoDB会对Next-Key Lock进行优化,将其降级为Record Lock,即仅锁住索引本身,而不是范围 。
虽然避免了幻读问题,但是还有个特殊情况,感觉可以叫做“幻改” , 即当前事务修改了本身并不能查询到的数据 。这也是MVCC造成的假象,当前事务虽然查询不到其他事务提交的数据,但是可以对其他事务提交的数据进行修改 。
oracle默认事务级别可导致重复读吗事务的隔离级别
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题 。
√: 可能出现×: 不会出现
脏读不可重复读幻读
Read uncommitted√√√
Read committed×√√
Repeatable read××√
Serializable×××
注意:我们讨论隔离级别的场景,主要是在多个事务并发的情况下,因此,接下来的讲解都围绕事务并发 。
Read uncommitted 读未提交
公司发工资了 , 领导把5000元打到singo的账号上,但是该事务并未提交,而 singo正好去查看账户 , 发现工资已经到账,是5000元整,非常高兴 。可是不幸的是 , 领导发现发给singo的工资金额不对,是2000元,于是迅速 回滚了事务 , 修改金额后,将事务提交,最后singo实际的工资只有2000元 , singo空欢喜一场 。
出现上述情况,即我们所说的脏读,两个并发的事务,“事务A:领导给singo发工资”、“事务B:singo查询工资账户”,事务B读取了事务A尚未提交的数据 。
当隔离级别设置为Read uncommitted时 , 就可能出现脏读,如何避免脏读 , 请看下一个隔离级别 。
Read committed 读提交
singo拿着工资卡去消费,系统读取到卡里确实有2000元,而此时她的老婆也正好 在网上转账,把singo工资卡的2000元转到另一账户,并在singo之前提交了事务,当singo扣款时,系统检查到singo的工资卡已经没有 钱 , 扣款失败,singo十分纳闷,明明卡里有钱,为何......
出现上述情况,即我们所说的不可重复读,两个并发的事务 , “事务A:singo消费”、“事务B:singo的老婆网上转账”,事务A事先读取了数据 , 事务B紧接了更新了数据,并提交了事务 , 而事务A再次读取该数据时,数据已经发生了改变 。
当隔离级别设置为Read committed时,避免了脏读 , 但是可能会造成不可重复读 。
大多数数据库的默认级别就是Read committed,比如Sql Server , Oracle 。如何解决不可重复读这一问题,请看下一个隔离级别 。
Repeatable read 重复读
当隔离级别设置为Repeatable read时,可以避免不可重复读 。当singo拿着工资卡去消费时,一旦系统开始读取工资卡信息(即事务开始),singo的老婆就不可能对该记录进行修改,也就是singo的老婆不能在此时转账 。
虽然Repeatable read避免了不可重复读,但还有可能出现幻读 。
singo的老婆工作在银行部门,她时常通过银行内部系统查看singo的信用卡消费 记录 。有一天 , 她正在查询到singo当月信用卡的总消费金额(select sum(amount) from transaction where month = 本月)为80元,而singo此时正好在外面胡吃海塞后在收银台买单,消费1000元 , 即新增了一条1000元的消费记录(insert transaction ... ),并提交了事务 , 随后singo的老婆将singo当月信用卡消费的明细打印到A4纸上,却发现消费总额为1080元,singo的老婆很诧异,以为出 现了幻觉,幻读就这样产生了 。
注:Mysql的默认隔离级别就是Repeatable read 。
Serializable 序列化
Serializable是最高的事务隔离级别,同时代价也花费最高 , 性能很低,一般很少使用 , 在该级别下,事务顺序执行 , 不仅可以避免脏读、不可重复读,还避免了幻像读 。
什么是oracle数据库隔离级别1.查看当前会话隔离级别
select @@tx_isolation;
2.查看系统当前隔离级别
select @@global.tx_isolation;
3.设置当前会话隔离级别
set session transaction isolatin level repeatable read;
4.设置系统当前隔离级别
set global transaction isolation level repeatable read;
5.命令行 , 开始事务时
set autocommit=off 或者 start transaction
关于隔离级别oracle如何支持幻读的理解
1.read uncommitted
可以看到未提交oracle如何支持幻读的数据(脏读),举个例子:别人说的话你都相信oracle如何支持幻读了,但是可能oracle如何支持幻读他只是说说,并不实际做 。
2.read committed
读取提交的数据 。但是,可能多次读取的数据结果不一致(不可重复读,幻读) 。用读写的观点就是:读取的行数据,可以写 。
3.repeatable read(MySQL默认隔离级别)
可以重复读?。谢枚?。读写观点:读取的数据行不可写 , 但是可以往表中新增数据 。在MySQL中,其他事务新增的数据,看不到 , 不会产生幻读 。采用多版本并发控制(MVCC)机制解决幻读问题 。
4.serializable
可读,不可写 。像java中的锁,写数据必须等待另一个事务结束 。
关于oracle如何支持幻读和oracle只读表可以执行哪些命令的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读