Oracle面试宝典-事务篇

Oracle 面试宝典 - 事务篇

 

请介绍下Oracle 事务的概念?

数据库管理系统提供了事务处理的机制以确保数据的完整性和一致性。

事务的使用是数据库管理系统与文件系统最重要的区别之一。

事务是包含一个或多个SQL 语句的逻辑原子工作单元。

事务对SQL 语句进行分组,使它们要么全部提交 ( 这意味着它们被应用到数据库 ) ,要么全部回滚 ( 这意味着它们从数据库撤消 ) 。只要有一条 SQL 语句执行失败,则已执行的 SQL 语句会回滚到执行之前的状态,这样就保证了数据库数据的一致性,不至于产生混乱的数据。

所有Oracle 事务都遵循数据库事务的基本属性,即 ACID 属性。 ACID 是以下内容的缩写 :

•原子性  Atomicity

事务必须是原子工作单元,对其进行的数据修改,要么全都执行,要么全都不执行。

强调事务的不可分割

例如: 银行转账, A B 转账 1000 元, 要在A 账户上 减少 1000 元,同时要在 B 账户上 增加 1000 元。 并且记录一条转账记录。 要么同时执行,要么都不执行更改,以确保整个事务是一个原子工作单元。

•一致性  Consistency

事务将数据库从一个一致状态转移到另一个一致状态。

强调事务执行前后, 数据库的完整性保持一致

例如, 银行转账,A B 账号转账 1000 元,是不允许看到 A 的账号减少 1000 B 的账号还没来得及增加 1000 的中间状态。

•隔离 Isolation

一个事务不会看到另外一个还未完成的事务产生的结果。每个事务就像在单独、隔离的环境下运行一样。

强调事务并发访问 一个事务的执行 不应该受到另一个事务的打扰

例如,一个用户正在更新 员工 表。其他用户 不会看到 员工表 所做的未提交更改。因此,在用户看来,事务似乎是串行执行的。

持久  Durability

提交的事务所做的更改是永久性的。 不会因为系统失败而丢失。

强调事务结束 数据永久保存数据库中

事务完成后,数据库通过其恢复机制确保事务中的更改不会丢失。

请介绍下事务有哪几种隔离级别,有什么区别?

SQL   标准定义的四个隔离级别为:   Read Uncommitted  未提交读     Read Committed  (提交读)、  Repeatable Read  (可重复读)、  Serializable  (可串行化)

隔离级别主要是为了防止三种现象发生: 脏读(Dirty Read), 不可重复读 (Nonrepeatable Read), 幻读 (Phantom Read)

脏读:

一个事务读取了另一个事务修改了但尚未提交的数据。

例如银行转账,A B 转了 1000 块钱,发生三步, A 账号减少 1000 元, B 账号增加 1000 元,记录转账信息。如果在刚完成第一步时, B 进行了脏读,发现自己已经多了 1000 元钱,但是之后 A 又执行了回退操作,这时 B 会发现多的 1000 没了。实际上转账并没有成功,在这种场景下脏读也不应该发生。

不可重复读

一个事务, 读到了另一个事务的提交数据(update , 导致查询结果不一致

在同一个事物中,同一个查询,例如select sal from hrtab where hid='chenjuchao', 9:00 时刻查询发现我的工资是 10000 ,在 9:05 时再次执行相同的查询,发现我的工资变成了 30000( 可能是另一个事务对我的工资进行了更改,并提交了更改 )

这样在同一个事物内,不同时间点执行同一个查询条件返回不一样的结果的现象,称为不可重复读。通常情况下,不可重复读是由于事务并发修改同一条记录导致的。

幻读:

一个事务, 读到了另一个事务的提交数据(insert) 导致查询结果不一致

同一事务中,当同一查询多次执行时,由于其他事务 插入操作的提交,会导致每次返回不同的结果集。幻读是事务非独立执行时发生的一种现象。

例如:在同一个事物内,9 点时刻,执行更新操作 update hrtab set sal=25000 where station='manage' and sal=20000; 将岗位是经理并且工资是 20000 的员工工资更 25000

更新成功后查询更新结果select * from hrtab where station='manage' and sal=20000; 发现还有一条记录没更新,可能的原因是在更新和查询之间,另一个事务执行了插入操作,

例如 insert into hrtab(sal,station,...) values(20000,'manage',...);

通常情况下,幻读是由于并发事务增加记录导致的。

隔离级别可预防的读现象

Oracle 数据库提供了 read committed( 默认 ) serializable 隔离级别。

Read Uncommitted  未提交读  

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果,不能解决脏读、不可重复读、幻读。并发性能最高,实际应用很少。

Read Committed  (提交读)

大多数数据库系统默认的隔离级别(Oracle SQLServer), 满足了隔离的简单定义,即一个事务只能查看其他事务已经提交的数据,可以解决脏读问题,不能解决不可重复读和幻读。并发性比 read uncommitted 低。

Repeatable Read  (可重复读)

可以确保同一事务,在多次读取相同条件的数据时,得到相同的结果。可以解决脏读和不可重复读问题,不能解决幻读问题。并发性比 Read Committed  低。

Serializable  (可串行化)

最高的隔离级别,通过强制事务排序,强制事务串行执行,使之不能相互冲突,可以解决脏读、不可重复读、幻读问题。但是并发性能最差 。实际情况下通常需要在完美的事务隔离和性能之间做出妥协。

隔离性: read uncommitted < read committed < repeatable read < serializable

并发效率: read uncommitted > read committed > repeatable read > serializable

欢迎关注我的微信公众号"IT Chen" ,共同学习,共同成长!!!

请使用浏览器的分享功能分享到微信等