admin 管理员组文章数量: 1086019
2023年12月23日发(作者:澳大利亚为何急于改善对华关系?)
1、 事务的概念:
事务是一个基本的逻辑单元,它作为一个整体要么全部执行要么全部不执行。
2、 事务的特性:
原子性:事务是处理的一个原子单位,每一个操作不可拆分,它要么全部执行成功,要么全部都不执行。
一致性:指事务完成时,必须使所有的数据在整体上不变。
隔离性:各事务之间相互隔离,此事务的执行不受其他并发事务执行的干扰。
持续性:指事务对数据库的改变应是持续存在的,不会因故障而发生丢失。
3、 从功能是上划分,sql语言分为DDL、DML和DCL:
3.1DDL(Data Definition Language,数据定义语言):
用于定义和管理数据库中的所有对象的语言,如:create创建表空间、alter修改表空间、drop删除表空间
3.2:DML(Data manipulation Language,数据操作语言):
处理数据等操作,如:insert插入数据、delete删除数据、update修改数据、select查询数据
3.3:DCL(Data Control Language,数据控制语言):
授予或回收访问数据库的权限,控制数据库操作事务发生的时间及效果,对数据库实行监视,如:grant授权,rollback回滚,commit提交
4、 事务的开始及结束:
一个事务可以由一条DDL语句单独组成或多条DML语句共同组成。一个事务从执行第一条sql语句开始,在它被提交或被回滚时结束。事务的提交可以是显式提交:用commit命令直接完成;也可以是提交隐式提交:用sql语句间接完成提交,这些语句有:alter,audit,comment,create,disconnect,drop,exit,grant,noaudit,quit,revoke,rename,会话终止等;还可以是自动提交:set autocommit on或set autocommit immediate设置为自动提交,则在插入、删除、修改语句执行后自动提交,使用set autocommit off可以取消自动提交,show
autocommit可以查看自动提交是否打开。事务的回滚使用rollback;语句,可以为事务设置保存点,如:savepoint point1,然后使用rollback to [savepoint] point1回到保存点point1,若在point1后又设置了一个保存点savepoint point2,则在rollback to point1后将不能再回滚到point2,因为point2在point1的后面,point1的保存点不存在point2。
5、 事务的并发性与一致性:
并发性:多个用户可以在同一时刻访问相同的数据。
一致性:保证并发性的同时,每个用户能得到一致的数据视图。
并发执行事务时,可能发生如下情况:
① 脏读:某个事务读取了其他未提交事务修改过的数据。
脏读示例:提交读隔离级别可防止脏读,但不能防止不可重复读
时间
T1
T2
T3
事务启动
从emp表中删除或增加记录
事务回滚
事务1
事务启动
基于事务1未提交的结果,计算员工总数
事务2
T4
② 不可重复读:某个事务读取一次数据后,其他事务修改了这些数据并进行了提交,这样当该事务重新读取这些数据时,就会得到与前一次读取不一致的结果。简单的说,就是同样的条件,你读取过的数据,再次读取时发现值不一样了。
不可重复读示例:可重复读隔离级别可防止脏读和不可重复读
时间
事务1 事务2
T1
T2
T3
T4
T5
T6
T7
事务以提交读模式启动
计算员工总工资
计算员工总工资
获取员工人数
计算平均薪水
事务启动
修改员工张三的工资
事务提交
③ 幻象:在某个事务执行第一次查询时获得了满足查询条件的一个结果集,随后其他事务又插入或删除了一些满足查询条件的记录,这样当该事务重新执行相同的查询时,会得到与前一次查询不一致的情况。简单的说,就是同样的条件,第一次和第二次读出来的记录数不一样了。
幻象示例:
时间
T1
T2
T3
T4
T5
T6
事务1
事务以可重复读模式启动
计算员工总薪水
计算员工总薪水
计算员工总人数
事务2
事务启动
添加一个员工
事务提交
计算平均工资
T7
④ 更新丢失:例如系统允许两个事务A、B同时更新同一数据50,A事务和B事务同时取得该数据,A事务将50加上50得到100,然后保存回数据库;而事务B将50加上100得到150,然后保存数据时覆盖了事务A保存的数据。两个事务更新后的数据本该是200,而结果A更新的50丢失了。
6、解决数据脏读、不可重复读等问题的隔离级别:
Oracle提供了三种隔离级别:Read Committed(提交读)、Serializable(串行读)、Read Only(只读)。
①Read Committed是Oracle默认隔离级别,若事务A先于事务B开始,事务B是Read
Committed隔离级别,则不管事务A是哪种隔离级别,只要事务A未提交,事务B就会一直处于等待状态,直到事务A提交为止。Read Committed消除了脏读,也不会丢失更新,但无法避免不可重复读和幻象读的发生。
②Serializable串行化隔离级别,确保事务顺序执行不被干扰,只要Serializable的事务在执行期间,其他事务要对其数据进行修改,便会发生无法序列化的访问错误,可以避免脏读、不可重复读、幻象、更新丢失,提供了最高级别的一致性,但并发性最低。
⑤ Read Only只读隔离级别不允许在事务内对其进行修改或插入等更新操作。Read Only可以消除脏读。
SQL-92规范制定的4种隔离级别:
☆未提交读(read uncommitted)
☆提交读(read committed)
☆可重复读(repeatable read)
☆串行读(serializable read)
总结:
隔离级别
未提交读
脏读
会 会
不可重复读
会
幻象
提交读
可重复读
串行读
不会
不会
不会
会
不会
不会
会
会
不会
7、 为事务或会话设置隔离级别:
设置一个事务的隔离级别:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; --设置Read Committed级别
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; --设置Serializable级别
SET TRANSACTION READ ONLY;--设置Read Only级别
设置整个会话的隔离级别:
ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;
ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;
8、 事务与锁
锁机制用于管理对共享资源的并发访问,防止访问相同资源时发生的有害性交互。基本上所有的锁都由oracle内部自动创建和维护,但是其中的DDL和DML锁是可以通过命令直接或间接管理的。
当事务在对某个数据对象进行操作前,先向系统发出请求,对其所访问的数据对象加锁,加锁后事务就对该数据对象有一定的控制,在该事务释放锁之前,其他事务不能对此数据对象进行更新操作。
Oracle提供的两种类型的锁机制:
① 独占锁:防止相关资源被共享,主要用来修改数据,只有在独占资源的事务释放独占锁后,其他事务才能对其资源进行操作。
② 共享锁:允许相关资源的共享,依赖于所包含的操作,多个用户读数据可以使用共享锁。
Oracle中锁的类型:
① 内部级锁:由Oracle自动管理,以保护Oracle的内部结构。
② DDL级锁(字典/语法分析锁):用于保护数据字典和数据定义改变时的一致性和完整性,由系统在对sql定义语句做语法分析时自动加锁,如该锁在使用create、drop、alter、truncate语句时自动创建,以确保在执行过程中没有其他事务对资源进行访问。DDL锁可分为三类:字典操作锁、字典定义锁、表定义锁。
③ DML级锁:用于控制并发事务中的数据操作,保证数据的一致性和完整性,其锁对象是表或行,在事务开始时创建,事务提交或回滚时释放。DML锁可以由用户以显式的方式加锁,也可以通过sql语句隐式加锁。
DML封锁技术:
Ⅰ、共享方式的表封锁(share):lock table 表名[,表名]… in share mode [nowait];
共享方式的表封锁是对表中的所有数据进行封锁,该锁用于保护查询数据的一致性,防止其他用户对已封锁的表进行更新,其他用户只能对该表再施加共享方式的锁,而不能再对该表施加独占方式的锁。共享该表的所有用户只能查询表中数据,不能更新,只能用sql语句加该锁。如下方式可以释放该锁:commit或rollback语句,退出数据库,程序停止运行。
Ⅱ、独占方式的表封锁(exclusive):lock table 表名[,表名]… in exclusive mode [nowait];
独占方式的表封锁对表中的所有数据进行封锁,拥有该独占方式的表封锁的用户,既可以查询该表又可以更新该表,其他用户不能再对该表施加任何锁,其他用户只可以查询该表。独占方式的表封锁还可以在执行DML语句insert、update、delete时隐式获得。如下方式可以释放该锁:commit或rollback语句,退出数据库,程序停止运行。
Ⅲ、共享更新方式封锁(share update):lock table 表名[,表名]… in share update mode
[nowait];或者
select 列名[,列名]…
from 表名
where 条件
for update of 列名[,列名]… [nowait];
共享更新方式封锁是对表的一行或多行进行封锁,也称为行级锁。该锁使得用户可以查询也可以更新被封锁的数据行,其他用户只能查询,若其他用户想更新表的数据行,则必须也要加共享更新方式锁,但其他用户的更新必须在上一个用户提交或回滚后才行。如下方式可以释放该锁:commit语句,退出数据库,程序停止运行。
9、 各锁的相容及互斥关系:(Y表示可以,N表示不可以)
用户1已加锁
share
Y
N
Y
N
exclusive
N
N
Y
N
shareupdate
N
N
Y
Y(在其他行上)
用户2操作
加share锁
加exclusive锁
加share update锁
更新数据(增、删、改)
10、死锁
下例便是一个死锁:
会话A更新表A 会话B更新表B
会话B更新表A--阻塞
会话A更新表B--导致死锁
Oracle处理死锁的方式:Oracle系统会自动发现死锁,并选择代价小的,即完成工作量最少的事务予以撤销,释放该事务所拥有的全部锁,让其他事务继续工作下去。
11、加锁的注意事项:
①对于update、delete操作,应只封锁要做改动的行,在完成修改后立即提交。
②当多个事务正利用共享更新的方式进行更新,则不要使用共享封锁,而应采用共享更新锁,这样其他用户就能使用行级锁,以增加并行性。
③尽可能将对一个表的操作的并发事务施加共享更新锁,从而提高并行性。
④在应用负荷较高的期间,不宜对基础数据结构(表、索引、簇、视图)进行修改。
12、加锁语句:
☆lock table 表名 in 锁定模式 mode [nowait];
解释:锁定模式为share表示共享锁(允许加锁,不许修改),为share update表示共享更新方式封锁,为exclusive表示独占锁(不许加锁,不许修改),为row share表示行级共享锁(允许加锁,不许修改),为row exclusive表示行级独占锁(不许加锁,不许修改),为share row
exclusive表示共享行级独占锁(对相应行加独占锁,对表加共享锁,其他事务可对其他行加独占锁)。nowait选项表示锁未添加成功时,则返回并由用户决定等待还是去执行其他语句。
☆添加行级共享锁:select … from 表名 for update;
☆create语句自动加共享锁,alter语句自动加独占锁,insert、update、delete语句自动添加行级独占锁。
版权声明:本文标题:Oracle的事务及锁 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/b/1703298395a445973.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论