分享

oracle事务与锁

 KILLKISS 2016-06-23

内容出于<<oracle从入门到精通(视频实战版)>>.读完这本书绝对不会精通oracle,内容简单入门,但比较全面的一本书.

一.事务有4个特性,它们分别是原子性,一致性,分离性,持久性.
1)原子性:事务的原子性是指,事务中程序是数据库的逻辑工作单位,它对数据的修改要么全部执行,要么完全不执行.原子也意味着不可分割,不管有多少程序,只要在同一个事务中,那么它们就是一个整体,如果都执行成功才意味着该事务成功,而有一个操作失败,那么同一个事务中的其他操作即使执行成功也没有用,事务会使其全部撤销.
2)一致性:事务的一致性指事务执行的前后数据库都必须处于一致性状态,它是相对脏读而言的.只有在事务完成后才能被所有使用者看见.保证了数据的完整性.例如在银行转账时,从A账户取款但没有放到B账户中时数据是不一致的,同时也是不完整的,其他使用者此时不能看到A中修改后的数据,只有存到B账户中,交易完成并提交事务,这时才算数据一致,所有用户也会看到修改后的数据.
3)分离性:分离性是指并发事务之间不能相互的干扰.也就是说,一个事务操作的数据不会被其他事务看到和操作.
4)持久性:持久性是指一旦事务提交完成,那么这将是对数据永久的修改,即使被修改的数据遭到破坏,也不会出现回到修改之前的情况.


二.锁
oracle处理数据时用到的锁是自动获取的,我们不用对此有过多的关注,但oracle允许我们手动锁定数据.oracle利用很低的约束提供了最大程序的并发性.例如某会话正在修改一条记录,那么仅仅该记录会被锁定.而其他会话可以随时做读取操作,但读取的依然是修改前的数据.
oracle的锁保证了数据的完整性.例如,当一人会话对表A的某行记录进行修改时,另一个会话也来修改该行记录,在没有任何处理的情况下保留的数据会有随时机,而这种数据是没有作保意义的,为脏数据.如果此时使用了行级锁,第一个会话修改记录时封锁该行,那么第二个会话此时只能等待,这样就避免了脏数据的产生.
锁的分类
两种模式锁:排他锁(X锁)和共享锁(S锁)
排他锁也叫写锁.这种模式的锁防止资源的共享,用做数据的修改.假如有事务T给数据A加上该锁,那么其他的事务将不能对A加任何的锁,所以此时只允许T对该数据进行读取和修改,直到事务完成将该类型的锁释放为止.
共享锁也可以叫读锁.该模式锁下的数据只能被读到,不能被修改.如果有事务T给数据A加上共享锁后,那么其他事务不能对其加排他锁,只能加共享锁.加了该锁的数据可以被并发地读取.锁是实现并发的主要手段,很多都是由数据库自动管理,当事务提交后会自动释放锁.


按作用对象又可分为DML锁,DDL锁和内部闩锁.
DML锁:该类型的锁被称为数据锁,用于保护数据.主要保证了并发访问时数据的完整性.再细分,又可分为行级锁(TX,也可叫事务锁)和表级锁(TM).
DDL锁:可以保护模式中的对象的结构.
内部闩锁:保护数据库的内部结构,完全自动调用.


1.TX:当修改表中的某行记录时,需要对将要修改的记录加行级锁,防止两个事务同时修改相同记录,事务结束,该锁也会释放,是粒度最细的锁.该锁只能属于排他锁(X锁).
2.TM:主要用用是防止在修改表的数据时,表结构发生变化.例如,会话S在修改表A的数据时它会得到表A的TM锁,而此时将不允许其他会话对该表进行变更或删除操作.表级锁包含如下几种模式:
RS(行级共享锁,ROW SHARE):该模式下不允许其他的并行会话对同一张表使用排它锁,但允许其利用DML语名或Lock命令锁定同一张表中的其他记录.select ...from for update语名就是给记录加上了RS锁.
RX(行级排他锁,ROW EXCLUSIVE):该模式下允许并行会话对同一张表的其他数据进行修改,但不允许并行会话对同一张表使用排他锁.
S(共享锁,SHARE):该模式下,不允许会话更新表,但允许对表添加RS锁.
SRX(共享行级排他锁,SHARE ROW EXCLUSIVE):该模式下,不能对同一张表进行DML操作,也不能添加S锁.
X(排他锁,EXCLUSIVE):该模式下,其他的并行会话不能对表DML和DDL操作,该表只能读.



死锁的一个例子:
打开两个会话S1和S2,这两个会话都设置会话自动提交为OFF
1.在会话S1执行:
update emp t set t.comm=320 where t.empno=7499;
但不要提交事务;
2.在会话S2执行:
update emp t set t.comm=520 where t.empno=7521;
但不要提交事务;
3.回到会话S1执行:
update emp t set t.comm=521 where t.empno=7521;
再执行提交,会发现提交不了.因为等待会话S2,而会话S2又在等待S1.
4.再回到会话S2执行
update emp t set t.comm=321 where t.empno=7499;
再执行提交,会发现出现了死锁.因为等待会话S1,而会话S1又在等待S2.


出现死锁,又不能自动解锁,那此时只能手动关闭对应的会话来解决这样的死循环等待锁,这种情况,之前执行的事务都会回滚.(注:关闭PLSQL Developer是会关闭当前会话,死锁当然就解决.),顺便提一下,正常退出sql*plus会自动提交事务,非正常退出则会回滚事务.PLSQL Developer正常退出但不明确写commit,也会提交事务.


要查看和关闭会话需要相应的权限(暂时不了解会话权限是什么名称),当一个用户赋予了dba权限,那么此用户就可以查看所有会话和关闭某个会话.
grant dba to scott;
PLSQL Developer来查看会话:工具-->会话
PLSQL Developer来关闭某个会话:从上面的会话列表中选择要关闭的会话-->右键选择关掉.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多