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语句自动添加行级独占锁。


本文标签: 事务 数据 提交 共享 执行