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
更多数据库相关学习资料,可以查看我的ITPUB博客,网名chenoracle:
http://blog.itpub.net/29785807/