事务:数据库操作的基本单位
一 事务的属性
事务具有ACID属性
即 Atomic原子性, Consistent一致性, Isolated隔离性, Durable永久性
原子性
就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全
回滚,全部不保留
一致性
事务完成或者撤销后,都应该处于一致的状态
隔离性
多个事务同时进行,它们之间应该互不干扰.应该防止一个事务处理其他事务也要修改的数据时,
不合理的存取和不完整的读取数据
永久性
事务提交以后,所做的工作就被永久的保存下来
二 事务并发处理会产生的问题
丢失更新
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题、
每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。
脏读
当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。
第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。
不可重复读
当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。
不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。
然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次
(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。
幻像读
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。
事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由
于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。
三 事务处理类型
自动处理事务
系统默认每个SQL命令都是事务处理 由系统自动开始并提交
隐式事务
当有大量的DDL 和DML命令执行时会自动开始,并一直保持到用户明确提交为止,切换隐式事务可以用SET
IMPLICIT_TRANSACTIONS
为连接设置隐性事务模式.当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为
OFF 时,则使连接返回到自动提交事务模式
用户定义事务
由用户来控制事务的开始和结束 命令有: begin tran commit tran rollback tran 命令
分布式事务
跨越多个服务器的事务称为分布式事务,sql server 可以由DTc microsoft distributed transaction
coordinator
来支持处理分布式事务,可以使用 BEgin distributed transaction 命令启动一个分布式事务处理
四 事务处理的隔离级别
使用SET TRANSACTION ISOLATION LEVEL来控制由连接发出的所有语句的默认事务锁定行为
从低到高依次是
READ UNCOMMITTED 此事务可以读取到其他事务未提交的修改结果
READ COMMITTED 此事务只能读取到其他事务提交的修改结果
REPEATABLE READ 如果在此事务中进行两次查询,则第一次查询的结果在第二次查询中不会发生改变,但第二次
查询结果中的记录条数可能会多于第一次查询的
SERIALIZABLE 此事务中两次查询结果完全相同
可以看见,一个事务隔离级别越高,用户越不会感觉到其他并发用户的存在
五、事务的控制命令
1) commit或commit work; commit命令结束一个事务,并且使得事务中的修改结果永久化
2) rollback或rollback work; rollback命令结束一个事务,并且通过undo表空间中的undo信息回滚事务对数据的所
有修改,从而把数据库回复到此事务开始之前的状态
3) savepoint 创建标志点
4) rollback to <savepoint>
5) set transaction 设置事务的一些属性
六、 commit的作用
1)释放事务中因为修改表中记录而产生的表
2)把重做缓冲区中的内容写入磁盘
3)把事务提交的时间写入重做日志文件,以表示数据库又处于一致状态的最后时刻
锁
锁是用来控制访问共享资源的一种机制。
Oracle中,有4个DML语句可能会引发阻塞:insert、update、delete、select for update
死锁:当两个用户各保持另外一个用户想要的资源时,会发生死锁。
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据
的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加
锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象
被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库
利用这两种基本的锁类型来对数据库的事务进行并发控制。
在实际应用中经常会遇到的与锁相关的异常情况,如由于等待锁事务被挂起、死锁等现象,如果不能及时地解决,将严
重影响应用的正常执行,而目前对于该类问题的解决缺乏系统化研究和指导,本文在总结实际经验的基础上,提出了相
应的解决方法和具体的分析过程。
Oracle数据库的锁类型
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性
;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩
(internal locks and latches),保护数据库的内部结构。
DML锁的目的在于保证并发情况下的数据完整性,本文主要讨论DML锁。在Oracle数据库中,DML锁主要包括TM锁和TX锁
,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。
当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,
并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检
查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。
不同的SQL操作产生不同类型的TM锁。如表1所示。
在数据行上只有X锁(排他锁)。在 Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持
到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的
会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。
当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错
误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。
TX锁等待的分析
在介绍了有关地Oracle数据库锁的种类后,下面讨论如何有效地监控和解决锁等待现象,及在产生死锁时如何定位死锁
的原因。
监控锁的相关视图 数据字典是Oracle数据库的重要组成部分,用户可以通过查询数据字典视图来获得数据库的信息。
和锁相关的数据字典视图如表2所示。
TX锁等待的监控和解决在日常工作中,如果发现在执行某条SQL时数据库长时间没有响应,很可能是产生了TX锁等待的
现象。为解决这个问题,首先应该找出持锁的事务,然后再进行相关的处理,如提交事务或强行中断事务。
死锁的监控和解决在数据库中,当两个或多个会话请求同一个资源时会产生死锁的现象。死锁的常见类型是行级锁死锁
和页级锁死锁,Oracle数据库中一般使用行级锁。下面主要讨论行级锁的死锁现象。
当Oracle检测到死锁产生时,中断并回滚死锁相关语句的执行,报ORA-00060的错误并记录在数据库的日志文件
alertSID.log中。同时在user_dump_dest下产生了一个跟踪文件,详细描述死锁的相关信息。
在日常工作中,如果发现在日志文件中记录了ora-00060的错误信息,则表明产生了死锁。这时需要找到对应的跟踪文
件,根据跟踪文件的信息定位产生的原因。
如果查询结果表明,死锁是由于bitmap索引引起的,将IND_T_PRODUCT_HIS_STATE索引改为normal索引后,即可解决死
锁的问题。
表1 Oracle的TM锁类型
锁模式 锁描述 解释 SQL操作
0 none
1 NULL 空 Select
2 SS(Row-S) 行级共享锁,其他对象只能查询这些数据行 Select for update、Lock for update、Lock row share
3 SX(Row-X) 行级排它锁,在提交前不允许做DML操作 Insert、Update、Delete、Lock row share
4 S(Share) 共享锁 Create index、Lock share
5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive
6 X(Exclusive) 排它锁 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive
表2 数据字典视图说明
视图名 描述 主要字段说明
v$session 查询会话的信息和锁的信息。 sid,serial#:表示会话信息。
program:表示会话的应用程序信息。
row_wait_obj#:表示等待的对象。
和dba_objects中的object_id相对应。
v$session_wait 查询等待的会话信息。 sid:表示持有锁的会话信息。
Seconds_in_wait:表示等待持续的时间信息
Event:表示会话等待的事件。
v$lock 列出系统中的所有的锁。 Sid:表示持有锁的会话信息。
Type:表示锁的类型。值包括TM和TX等。
ID1:表示锁的对象标识。
lmode,request:表示会话等待的锁模式的信
息。用数字0-6表示,和表1相对应。
dba_locks 对v$lock的格式化视图。 Session_id:和v$lock中的Sid对应。
Lock_type:和v$lock中的type对应。
Lock_ID1: 和v$lock中的ID1对应。
Mode_held,mode_requested:和v$lock中
的lmode,request相对应。
v$locked_object 只包含DML的锁信息,包括回滚段和会话信息。 Xidusn,xidslot,xidsqn:表示回滚段信息。和
v$transaction相关联。
Object_id:表示被锁对象标识。
Session_id:表示持有锁的会话信息。
Locked_mode:表示会话等待的锁模式的信
息,和v$lock中的lmode一致。