Oracle事务和锁
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle事务和锁相关的知识,希望对你有一定的参考价值。
事务:
定义:事务就是一组包含一条或多条语句的逻辑单元,每个事务都是一个原子单位,在事务中的语句作为一个整体,要么一起被提交,作用在数据库上,是数据库数据永久被修改,要么一起被撤销,对数据不做任何修改。主要用于保证数据一致性。
例子:
账户A提取1000元,放入账户B,并将该操作记录日志。
事务基本控制语句:
SET TRANSACTION:设置事务属性
COMMIT:提交事务
SAVEPOINT:设置保存点
ROLLBACK:回滚事务
ROLLBACK TO SAVEPOINT:回滚至保存点
事务的类型:
显式事务:就是利用命令完成,自行设置commit/rollback,来设置提交或回滚,oracle不像java,不用设置开始标识,事务会开启;(登陆数据库后第一次执行dml语句便是事务的开始;当上一个事务结束,第一次执行dml则开始下一个事务 )
隐式事务:不需要自行设置commit/rollback。如
a.当一个程序正常结束,如使用sql plus退出时,之前的sql都会commit;
b.ddl语句自动提交
c.set autocommit on/off(默认是off,则所有dml都是显示事务,需要自行设置commin/rollback),on则每次执行dml系统都自动提交或回滚。
事务的保存点:
类似将一个长的事务划分为多个短事务,短事务结束后,标记一个SAVEPOINT name,下一个事务提交出问题时,可指定rollback to name来回滚到name结束处。保存点的好处是当出现问题时不需要全部回滚。
a.事务只回滚到保存点之后的操作
b.回滚到某保存点时,它以后的保存点将被删除,但之前的保存点将被保留
c.保存点之后的锁将被释放,但之前的会被保留。
不要过分依赖保存点,应尽量把长的事务改成较短的事务操作。
事务的ACID:原子性、一致性、分离性、持久性。
注意点:
***在oracle中事务的使用,事务的结束情况1.当autocommit为off(默认)时,记得自己设置commit/rollback,2.执行ddl时,自动提交,3.sql*plus正常退出时,commit,异常退出时,rollback.
***当前会话执行事务未提交时,其他会话看不到当前会话的修改,但当前会话可见,例如当前会话修改了一条数据,当前会话再查询则查询到修改后的数据
锁:
oracle利用很低的约束提供了最大程度的并发性,当一个会话在修改某行记录时,仅仅该行会被锁定,其他会话可以随时读取,且读取的数据还是修改之前的数据,锁可以保证事务的分离性,防止事务交互造成数据不一致。数据库中的锁很多都是相同自动添加和释放的,如提交事务,oracle也允许我们手动设置。
锁从操作权限上分可分为写锁和读锁:
排他锁(写锁/X锁/读写锁):修改数据时用,排他,即当事务T对数据A添加排他锁,则其他事务不可再对该数据添加任何锁,此时只允许事务T对数据A进行读写,其他事务应该可以读取。
共享锁(读锁/S锁/只读锁):共享锁下数据只能被读取,不能修改。数据已经被加了共享锁情况下,不可再加排他锁,但可被加共享锁。
从锁的作用对象分:
DML锁:数据锁,用于保护数据。是指执行dml时使用的锁,分为行级锁(TX,又称事务锁)和表级锁(TM)。
行级锁是在修改某行记录时对该行数据锁定,不允许其他事务修改,属于排他锁;
表级锁用于防止修改数据时表的结构发生变化。事务在修改数据时会先获取表级锁,再获取行级锁。所以当事务A在修改数据时,不允许任何事务修改表结构。
当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型锁。当TM锁获得后,系统再自动申请TX类型锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了RS、RX、S、SRX、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁
(1)行共享 (ROW SHARE) – 属共享锁 ,禁止排他锁定表,
(2)行排他(ROW EXCLUSIVE) – 禁止使用排他锁和共享锁
(3)共享锁(SHARE)-锁定表,仅允许其他用户查询表中的行,禁止其他用户插入、更新和删除行,多个用户可以同时在同一个表上应用此锁
(5)共享行排他(SHARE ROW EXCLUSIVE) – 比共享锁更多的限制,禁止使用共享锁及更高的锁
(6)排他(EXCLUSIVE) – 限制最强的表锁,仅允许其他用户查询该表的行。禁止修改和锁定表
行级锁:
(下面这句将给该表的所有行都加上锁)
select * from person for update;
如果该行记录已经被锁定,就不用等待,系统会直接抛错 ora-00054
select * from person where id = ‘1‘ for update nowait
如果该行记录已经被锁定,更新的时候等待5秒,如果这5秒内,该行记录被解锁,那么返回查询结果,如果5秒内仍未解锁,那么系统会直接抛错 ora-00054
select * from person for update wait 5;
另外,如果使用 select * from person where id = ‘1‘ for update ,当该行记录已经被锁定时,那么系统将一直等待该行记录被释放后,再加锁。
表级锁:
行共享:允许用户进行任何操作,禁止排他锁
lock table person in row share mode;
行排他:允许用户进行任何操作,禁止共享锁和排他锁
lock table person in row exclusive mode;
共享锁:其他用户只能看,不能修改
lock table person in share mode;
共享行排他:比共享锁有更多限制
lock table person in share row exclusive mode;
排他锁:其他用户只能看,不能修改,不能加其他锁
lock table person in exclusive mode;
对于通过lock table命令主动添加的锁定来说,如果要释放它们,只需要发出rollback命令即可
根据锁的类型分,共有6种
1、NULL,可以某些情况下,如分布式数据库的查询会产生此锁。
2、RS,表结构共享锁
3、RX,表结构共享锁+被操作的记录的排它锁
4、S, 表结构共享锁+所有记录共享锁(表结构只读和所有行记录只读)
5、SRX,表结构共享锁+所有记录排它锁
6、X 表结构排它锁+所有记录排它锁,自己可以修改和查看表结构及数据,其他事务只能读
select * from able_name for update是RX,据说老版本文档说的是RS,以后的是RX
http://blog.chinaunix.net/uid-25909722-id-3387609.html
锁定和解锁:在oracle中执行dml自动为表添加TM锁,也可用lock手动添加,使用rollback则解锁
DDL锁:用于保护对象的结构,数据字典,表结构等,用户不能显示地要求使用ddl锁
内部闩锁:保护数据库的内部结果,完全由系统自行调用。
本文出自 “11950462” 博客,谢绝转载!
以上是关于Oracle事务和锁的主要内容,如果未能解决你的问题,请参考以下文章
操作-oracle (游标-数据的缓冲区视图-数据库中虚拟的表存储过程-提高程序执行效率触发性-保证数据的正确性事务和锁-确保数据安全控制文件和日志文件)