频道栏目
首页 > 资讯 > Sybase > 正文

数据库事务

15-06-01        来源:[db:作者]  
收藏   我要投稿

事务的概念:

事务是多用户数据库的重要机制,事务处理是所有RDBMS(当然包括Oracle)的核心。事实上,没有事务处理,就没有RDBMS实现的可能性。事务处理技术主要包括数据库的恢复技术和并发控制技术。据库恢复技术和并发控制技术是数据库管理系统的重要组成部分。数据的安全保护措施是否有效,是衡量数据库好坏的主要性能指标之一。
Oracle提供了一种“事务”的控制机制,能够保证对数据进行有效、安全的操作,使数据库中的数据始终牌一个数据一致性的状态。在关系数据库中,
事务(Transaction)是一系列的数据库操作,由一条或多条相关的SQL语句组成,是数据库应用程序的基本逻辑单位。数据存储的逻辑单位是数据块,数据操作的逻辑单位是事务。事务与应用程序是两个不同的概念。通常情况下,一个应用程序包括多个事务。事务是用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位。
事务就是一组包含一条或多条语句的逻辑单元,每个事物都是一个原子单位,在事物中的语句被作为一个整体,要么被一起提交,作用在数据库上,使数据库数据永久的修改,要么一起撤销对数据库不做任何修改。

事务的ACID特性:

事务具有四大性质,包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。它们可简称为事务的ACID特性。

------------------------

原子性:

事务是数据库中一个不可分割的逻辑单位(或操作序列),一个事务中的所有操作要么都被成功地做完,要么都不做。只要有一个不成功,就会被自动回退。否则数据库中的数据就会处于一个不一致状态。未提交对数据的更新操作是可以被退回的,提交之后的更新操作是不能被回退的,可以手动回退或手动提交。
------------------------

一致性:

一致性是指一个语句、一个事务操作后的结果(事务执行的结果)必须要使数据库中的所有数据处于一种逻辑上的一致性状态。换言之,数据库必须从一个一致性状态到另一个一致性状态。如在语句、事务处理开始之前,数据库中的所有数据都是满足已经设置的各种约束条件或业务规则的,在语句、事务处理完成之后,数据虽然不同以往,但它们必须仍然满足先前设置的约束条件或业务规则。
------------------------

隔离性:

隔离性是指事务的执行不能被其他的事务所干扰。即一个事务内部的操作与使用的数据,对其他事务是隔离的,并发执行的各个事务之间不能互相干扰。在提交之前,只有该事务的用户才能够操作以正在修改的数据,而其他事务的用户只能看到修改之前的数据。
隔离性是数据库允许对其中的数据并发修改和读取的能力。如果没有隔离性,一个事务就有可能读取另一个事务正在操作的、但还没有提交的、设置还可能处于回退的中间数据,而因此做出的错误的操作或决策。
------------------------

持续性:

持续性也称为永久性,它是指一个事务一旦被提交成功,它对数据库中的数据所做的修改也就永久地保存下来了。这些修改不会由于系统故障或错误而消失。换言之,这个数据一致性的状态是可以被恢复的,不会被丢失的。接下来的其他操作都是在些基础上进行的,不会对其执行结果有任何影响。

Oracle提供的事务控制是隐式自动开始的,它不需要用户显示地使用语句开始事务处理。
但该事务控制也包括以下几种语言:
提交事务(COMMIT)、
回退事务(ROLLBACK)、
设置保存点(SAVEPOINT)、
回退到保存点(ROLLBACK TO SAVEPOINT)、设
置事务的属性(SET TRANSACTION)、
设置可延迟约束的检验时机(SET CONSTRANTS)。

事物在没有提交之前可以回滚、而且在提交前用户可以查看已经修改的数据,但其他用户查看不到,一旦事物提交就不能再撤销修改了。
Oracle的事物基本控制语句有如下几个:
SET TRANSACTION:设置事物的属性
COMMIT:提交事物
SAVEPOINT:设置保存点
ROLLBACK:回滚事物
ROLLBACK TO SAVEPOINT:回滚至保存点

事务的开始与结束

开始

事务是用来分隔数据库操作的逻辑单位,因此事务是有起点和终点的。Oracle的一个重要特点就是没有“开始事务处理”的语句。用户不能也不必显式地开始一个事务处理。
当发生如下事件之一时,事务就开始了。
(1)连接到数据库,并开始执行第一条DML语句时;
(2)当一个事务结束或者执行一条会自动提交事务的语句时。

结束

当发生如下事件之一,事务就结束了:
(1)执行一条会自动提交事务的语句时;
(2)显式地使用提交(Commit)语句或回滚(Rollback)语句时;
(3)执行一条DML语句该语句却失败了,此时会因为这个失败的DML语句而自动回退事务;
(4)在SQL*PLUS中,正常的退出(使用exit命令或是quit命令),Oracle会自动对事务进行提交;
(5)如果直接关闭SQL*PLUS,会自动对事务进行回滚;
(6)在SQL*PLUS中,Autocommit设置为ON,事务也会自动提交;
(7)在执行SQL*PLUS中,如遇到计算机突然断电、崩溃等,就会自动执行Rollback语句;
(8)执行一条DDL语句(如Create Table, Alter Table, Drop Table, Alter System)后;
(9)执行一条DCL语句(如 Grant, Revoke, Audit, Noaudit, Rename)后;
(10)断开与数据库的连接时。

提交与回滚事务

一般来说,当一个事务的逻辑单位结束时,或者应该用Commit语句提交,或者应该用Rollback语句回退。

提交事务

在用DML语句对数据库进行操作之后,如果要在数据库中永久性地保存操作结果,就需要使用Commit命令来提交事务。也就是说,通知数据库管理系统将该事务对数据库所做的操作全部保存到操作系统中。注意:至少要先保存到“重做日志文件”中,然后再保存到“数据文件”中。提交成功之后,其他会话就可以查看到操作后的数据了。

回退事务

如果不想让执行的SQL语句生效,就需要使用Rollback语句回退事务。回退一个事务就意味着在该事务中对数据库进行的全部操作被撤销,Oracle利用回退来修改存储前的数据,通过重做日志来记录对数据所做的修改。也就是说,回退可以终止用户的事务处理,并撤销用户已经进行的所有更改。
从事务开始到回退时的所有SQL语句的操作都不会被记录到数据库中。换言之,如果在对数据库的修改过程中出现了程序数据库方面的错误,或用户不打算保存他们所做的操作结果时就可以使用Rollback命令来回退全部事务。将该事务目前对数据库所做的更改全部回退到上一个提交成功的状态。
与提交事务不同,回退事务所需要的时间取决于所要撤销的数据库操作或逐句的数量。显然,这是因为回退事务必须要在物理上撤销所做的操作。回退的功能是一个对错误的异常处理办法,非常时期(系统停/断电、人为破坏等特殊情况)是必需的。正常时不要使用,否则就无法在数据库中保留操作的结果了。
当进行部分回退的时候,Oracle执行的任务是:
(1)撤销保存点之后所胡已经执行的更改,但保留保存点之前的更改。
(2)释放保存点之后各个SQL语句所占用的系统资源,并解除对所涉及的操作对象的锁定。但保留保存点之前各个SQL语句所占用的系统资源和对所涉及的操作对象的锁定。
(3)给用户返回一个回退到保存点的成功提示的代码。
(4)用户可以继续执行当前的事务。

并发事务

并发事务的问题:

对数据的保护包含两方面的内容:
防止合法用户的操作对数据库造成意外的破坏;
防止非法用户的操作对数据库造成故意的破坏。
数据库的基本特征就是允许多用户并发访问。虽然很多的用户并发访问,能提高数据资源的使用效率,但是也会引起资源的争用和数据不一致等一系列的问题。
事务是并发控制的基本单位,保证了事务ACID特性是事务处理的重要任务。事务的特性受到破坏原因之一就是多个事务对数据库的并发操作所造成的结果
在并发事务情况下,存在3种现象会对数据库造成破坏:

(1)读“脏”数据 (Dirty Read)--脏读:

一个事务读取到了另一个事务中还没有提交、更改过的数据。其效果就像是打开了其他人正在更改的WORD,不是最后的定稿的文档。在这种情况下,数据可能并不是一致性的。

(2)不可重复读(Non-Repeatable Read):

当一个事务T1读取了一些数据后,另一个事务T2修改了这些数据并进行了提交。这样一来,当该T1事务再次读这些数据时,发现这些数据已经被修改了。

(3)丢失修改(Lost Update):

两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。

事务锁

数据库是一个庞大的多用户数据管理系统,由于在多用户的系统中,同一时刻多个用户同时操作某相同资源的情况时有发生,逻辑上这些用户想同时操作该资源是不可能的,数据库利用锁消除多用户操作同一资源时可能产生的隐患。

分类
并发操作带来的3大问题的原因就是在于并发操作破环了事务的隔离性。那么该如何解决这3个问题呢?我们所使用的方法就是—锁。
锁就是对某个资源或是对象加以锁定,从而起到限制和防止其他用户访问的作用,保证数据的一致性和完整性。
锁是Oracle数据库用来控制并发访问的一种很重要的机制。
它的基本类型分为两种:一种是排它锁,另一种是共享锁。

排他锁(Exclusive Lock)又称X锁:

如果一个事务在某个数据对象上建立了排他称,那么只有该事务可以对该数据对象进行修改、插入和删除等更新操作,而其他事务则不能对该数据对象加上任何类型的锁;

共享锁(Share Lock)又称S锁。

如果一个事务在某个数据对象上建立了共享锁,则该事务可以对数据对象进行读操作,进而能进行修改、删除等更新操作,其他的事务也只能对该数据对象加上S锁进行读取,而不能加上X锁进行修改、删除等更新操作。

加锁

一般情况下,锁是由Oracle数据库自动维护的,一般的查询语句是不用加任何锁的。执行DDL、DML操作的时候,Oracle数据库会自动进行加锁,这时你也可以选择手动的方式用语句进行加锁。
手动方式加锁分为LOCK TABLE语句对表加锁和SELECT FOR UPDATE语句对行记录进行加锁

1)LOCK TABLE语句

LOCK TABLE语句的语法格式为:
Lock table talbe_name in lockmode nowait/wait n
其中,table_name指定要锁定的表或视图;lockmode表示锁定的模式,选项有row exclusive、share、row share、 share row exclusive和exclusive;wait关键字表示用于指定等待其他用户释放锁的秒数,防止无期限的等待;nowait关键字表示不必等待要锁定的表上的锁释放而直接返回。

(2)select for update语句

select for update语句允许用户一次锁定多条记录。
它的语法格式为:
select 语句 for update[of column][wait n/nowait][skip lock]
其中,of关键字指出将要更新的列,锁定行上的特定的列;wait关键字表示等待其他用户释放锁的秒数,防止 无何止的等待;nowait关键字表示不必等待锁定的数据行上的锁释放可直接返回;使用skip lock子句表示可超过锁定的行,不会报告由wait n引发的异常报告。

锁等待

在某些情况下由于占用的资源不能及时释放,而造成锁等待,也可叫锁冲突。例如,当一个会话修改表A的记录时,它会对该记录加锁,而此时另一个会话也来修改此记录,那么第二个会话因得不到排他锁而一直等待,会出现长时间没有响应的现象,直到第一个会话把事物提交,释放锁,第二个回话才能对数据库进行操作。

死锁

死锁是锁等待的一个特例,通常发生在两个或多个会话间。假设一个会话想要修改两个资源对象,修改两个资源的操作在一个事物当中。当它修改第一个对象时需要对其锁定,然后等待第二个对象。这是如果另外一个会话也需要修改这两个资源对象,并且已经获得并锁定了第二个对象,那么就会出现死锁。因为当前会话锁定了第一个对象等待第二个对象,而另一个会话锁定了第二个对象等待第一个对象,这样两个会话都得不到想要得到的对象,于是出现死锁。


应用实例:

--建表语句
-- Create table
create table EMP
(
  empno    NUMBER(4) not null,
  ename    VARCHAR2(10),
  job      VARCHAR2(9),
  mgr      NUMBER(4),
  hiredate DATE,
  sal      NUMBER(7,2),
  comm     NUMBER(7,2),
  deptno   NUMBER(2)
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints
alter table EMP
  add constraint PK_EMP primary key (EMPNO)
  using index
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
alter table EMP
  add constraint FK_DEPTNO foreign key (DEPTNO)
  references DEPT (DEPTNO);
-
--Oracle默认开启事务:
insert into emp(empno,ename) values(8461,'test');
rollback;
commit;

--关闭/开启事务:
set autocommit on/off;


--保存点
--    在事物中可以根据自己的需要设置保存点,保存点可以设置在事物的任何地方,也可以设置多个点,这样就可以把比较长的事物根据需要分成小段,
--当数据出现问题时可以不用全部回滚,只需要回滚到保存点即可。
insert into emp(empno,ename) values(8471,'test1');
savepoint first;
insert into emp(empno,ename) values(8472,'test1');
savepoint second;
insert into emp(empno,ename) values(8473,'test3');
savepoint third;
insert into emp(empno,ename) values(8474,'test4');
#回滚到savepoint second,保存点second之前的test1和test2将会被提交
rollback to second;
commit;



相关TAG标签
上一篇:weblogic项目部署方式选择分析
下一篇:sql简单查询,限定查询及排序
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站