43. SQL -- 事务(1)

 

的概念

是一个用的完整的工作元,一个事内的所有句被作整体行,要全部行,要全部不行。遇到错误时,可以回,取消事内所做的所有改,从而保数据中数据的一致性和可恢性。

 

数据(Database Transaction) ,是指作为单逻辑工作行的一系列操作。

 

数据的一个例子是将从一个号中到另外一个号中。此通常包含两操作:一条UPDATE 负责从一个号的总额中减去一定的数,另外一条UPDATE 负责向另外一个号中增加相数。

 

操作流程:

想网上物的一次交易,其付款程至少包括以下几数据操作:

更新客商品的存信息

保存客付款信息--可能包括与行系的交互

生成订单并且保存到数据

更新用信息,例如物数量等等正常的情况下,些操作将行,最交易成功,与交易相的所有数据信息

也成功地更新。但是,如果在一系列程中任何一个环节出了差,例如在更新商品存信息时发生异常、该顾帐户存款不足等,都将致交易失。一旦交易失,数据中所有信息都必保持交易前的状,比如最后一更新用信息致交易失,那证这笔失的交易不影响数据的状--存信息没有被更新、用也没有付款,订单也没有生成。否,数据的信息将会一片混乱而不可预测

 

数据正是用来保证这种情况下交易的平性和可预测性的技

的特性

原子性(atomic)(atomicity)

是原子工作元;于其数据修改,要全都行,要全都不行。

一致性consistent(consistency)

在完成,必使所有的数据都保持一致状。例如,当开发用于转帐用程序避免在转帐过程中任意移小数点。

隔离性insulation(isolation)

由并所作的修改必与任何其它并所作的修改隔离。事务查看数据数据所的状,要是另一并修改它之前的状

用程序降低隔离级别取更大的吐量。防止数据

持久性Duration(durability

完成之后,它于系的影响是永久性的。修改即使出致命的系故障也将一直保持。

 

与批的区

,一定要区分事和批的差

批是一整体编译SQL 句,事是一为单逻辑工作行的SQL 句。

句的生在编译时刻,事句的生在刻。

当在编译时,批中某个句存在错误,系将取消整个批中所有行,而在运行刻,如果事中某个数据修改束、规则等,系将回整个事物。

如果批内生一个运行错误,系只回退到该错误句。一个事中也可以有多个批,一个批里可以有多个SQL 成的事,事内批的多少不影响事的提交或回操作

 

务对控制和保障数据完整的重要性

与并控控制的

数据一个明的特点是多个用共享数据库资源,尤其是多个用可以同存取相同数据。

串行控制:如果事行的,即一个事完成之后,再始另一个事并行控制:如果DBMS 可以同接受多个事,并且些事时间上可以重叠行事是并控制的基本位,保ACID 的特性是事务处理的重要任,而并操作有可能会破坏其ACID 特性。

DBMS 控制机制的任:

操作行正确度,保的隔离性更一般,确保数据的一致性。如果没有定且多个用时访问一个数据当他的事使用相同的数据可能会问题由于并操作来的数据不一致性包括:失数据修改、读‖脏‖数据(脏读)、不可重复读生幽灵数据。

1失数据修改

当两个或多个事务选择同一行,然后基于最初定的更新,会失更新问题个事都不知道其它事的存在。最后的更新将重写由其它事所做的更新,致数据失。再例如,两个编辑制作了同一文档的本。编辑独立地更改其本,然后保存更改后的本,这样就覆盖了原始文档。最后保存其更改本的编辑覆盖了第一个编辑所做的更改。如果在第一个编辑完成之后第二个编辑才能行更改,可以避免该问题

2�D脏‖数据(脏读

�D脏‖数据是指事T1 修改某一数据,并将其写回磁,事T2 取同一数据后,T1 由于某原因被除撤消,而此T1 把已修改的数据又恢T2 到的数据与数据的数据不一致,T2 到的数据就�D脏‖数据,即不正确的数据。例如:一个编辑正在更改子文档。在更改程中,另一个编辑员复制了文档(该复本包含到目前止所做的全部更改)并将其分发给预期的用。此后,第一个编辑员认为目前所做的更改是错误的,于是除了所做的编辑并保存了文档。分发给的文档包含不再存在的编辑内容,并且编辑内容应认为从未存在。如果在第一个编辑确定最更改前任何人都不能取更改的文档,可以避免该问题

3)不可重复读

指事T1 取数据后,事T2 行更新操作,使T1 无法取前一次果。不可重复读包括三情况:

T1 取某一数据后,T2 其做了修改,当T1 再次读该数据后,得到与前一不同的

4生幽灵数据

按一定条件从数据取了某些记录后,T2 除了其中部分记录,当T1 再次按相同条件取数据发现某些记录消失T1 按一定条件从数据取某些数据记录后,T2 插入了一些记录,当T1 再次按相同条件取数据发现多了一些记录

务对保障数据一致和完整性的作用

故障轻则造成运行事非正常中断,影响数据中数据的正确性,重破坏数据,使数据中全部或部分数据失 。影响事正常运行的故障有:

1)事内部的故障

2)系故障

3)介故障

4算机病毒

及控制

 

的分

SQL Server 的事模式可分式事式事和自

1). 式事

式事是指由用户执T-sql 务语句而定的事这类又称做用。定句包括:

BEGIN TRANSACTION:标识一个事始,即启

COMMIT TRANSACTIONCOMMIT WORK标识一个事束,事内所修改的数据被永久保存到数据中。

ROLLBACK TRANSACTIONROLLBACKWORK标识一个事束,明事务执程中遇到错误,事内所修改的数据被回到事务执行前的状

2). 式事

式事模式下,在当前事提交或回后,SQL Server动开始下一个事。所以,式事不需要使用BEGIN TRANSACTION 句启,而只需要用使用ROLLBACKTRANSACTIONROLLBACK WORKCOMMIT TRANSACTIONCOMMIT

WORK 句提交或回。在提交或回后,SQL Server动开始下一个事SET IMPLICIT_TRANSACTIONS ON 句可使SQL Server式事模式。在式事模式下,当行下面任意一个,可使SQL Server重新启一个事

所有CREATE ALTERTABLE 所有DROP

TRUNCATE TABLE GRANT REVOKE

INSERT UPDATE DELETE

SELECT OPEN FETCH需要关闭隐式事模式SET 关闭IMPLICIT_TRANSACTIONS OFF 选项即可。

3). 模式

在自模式下,当一个句被成功行后,它被自提交,而当它程中错误时,被自。自模式是SQL Server的默管理模式,当与SQL Server建立接后,直接入自模式,直到使用BEGINTRANSACTION 始一个式事,或者打IMPLICIT_TRANSACTIONS 选项进式事模式止。

而当式事被提交或IMPLICIT_TRANSACTIONS关闭后,SQL Server 入自管理模式。

DEMO

BEGIN TRAN

SELECT * FROM Student

INSERT INTO Student

VALUES(,, )

SELECT * FROM Student

ROLLBACK -- 整个事

COMMIT -- 提交事

 

控制

SQL Server 中有句有:

命令名 作用 格式

BEGIN TRANSACTION 明一个事务开BEGINTRANsaction [<>]

COMMIT TRANSACTION

明一个事务结束,它的作用是提

交或确完成

COMMIT TRANsaction [<>]

SAVE TRANSACTION

用于在事置一个保存点,目的是在撤消事务时可以只撤消部

分事,以提高系的效率

SAVE TRANsaction <保存点>

ROLLBACK

TRANSACTION

明要撤消事,即撤消在数据所做的更新操作,使数

回退到BEGINTRANSACTION或保存点之前的状

ROLLBACK TRANsaction [<>| <保存

>]

1的提交和回

要永久性地记录SQL句的果,需要COMMIT句,从而提交(commit)。要取消SQL 句的果,需要ROLLBACK 句,从而回(rollback),将所有行重新原始状

DEMO1下面个例子向orders 表中添加一行,然后COMMIT 句,永久性地保存数据行的修改

BEGIN TRANsaction complete

INSERT INTO orders

VALUES ('p04','2011-09-10 00:00:00.000','ded','EN','4000',convert(varbinary(256),

pwdencrypt('passw0rd')))

Commit TRANsaction complete

查询显示添加的新行

select * from orders

DEMO2: 下面个例子更新P01 的内容,然后行一条ROLLBACK 句,取消数据行的修改:

begin transaction up_cust

update orders

set cust = 'oef'

where docno = 'p01'

Rollback transaction up_cust

查询显示更改p01 的数据被rollback 到了之前的状.

select * from orders

(2) 始与

是用来分割SQL 句的逻辑工作元。事既有起点,也有点;

当下列事件之一,事始了:

接到数据上,并行一条DML (INSERTUPDATEDELETE)

前一个事务结束后,又入了另外一条DML 句。当下列事件之一,事束了:

COMMIT ROLLBACK句。

行一条DDL 句,例如CREATE TABLE 句;在这种情况下,会自动执COMMIT句。

行一条DCL 句,例如GRANT 句;在这种情况下,会自动执COMMIT 句。

与数据接。在退出SQL*Plus ,通常会EXIT 命令,此会自动执COMMIT 句。如果SQL*Plus 被意外止了(例如运行SQL*Plus 算机崩),那就会自动执ROLLBACK 句。适用于任何可能访问数据的程序。例如,如果写了一个可以访问数据Java 程序,而个程序崩了,那就会自动执ROLLBACK 句。

行了一条DML 句,该语句却失了;在这种情况中,会为这个无效的DML ROLLBACK 句。

3) 保存点

在事中的任何地方都可以置一个保存点(savepoint)这样可以将修改回到保存点。如果有一个很大的事将非常有用,因为这样如果在保存点后行了操作,并不需要将整个事一直回到最开头。但是保存点不能肆意乱用;最好是重新整一下事构,将其转换为较小的事

DEMO:下面将出一个使用保存点的例子

始之前,首先来检查一下p01 p02的当前价格:

select docno,rate

from orders

where docno in('p01','p02')

P01 的价格是5000p02 的价格是6000p01 品价格提高20%p02 品价格提高30%

建一个事,更新p01 品的价格,并保存点.

begin transaction up_rate

update orders

set rate = rate * 1.2

where docno = 'p01' --更新p01品价格,增加20%

save transaction up_p01 --保存点

update orders

set rate = rate * 1.3

where docno = 'p02' --更新p02 品价格,增加30%

--时查查询结果:

--selectdocno,rate

--fromorders

--wheredocno in('p01','p02')

未修改前果:

可以看到,通过上面事务语句,已将产品p01 p02 的价格做了更新

下面这条语句用于使事务回滚到保存点的位置:

ROLLBACKtransaction up_p01

此时执行一条回滚语句到保存点,查看返回结果:

--selectdocno,rate

--fromorders

--wheredocno in('p01','p02')

未修改前结果:

可以看到,此时仅对产品p01 做了修改,对p02 所做的修改回滚到了保存点的位置.下面这条语句用于使事务回滚到事务开始前的位置.

rollbacktransaction up_rate

此时执行一条回滚语句到保存点,查看返回结果:

--selectdocno,rate

--fromorders

--wheredocno in('p01','p02')

可以看到,此时回滚到了未修改前的结果.

说明:

在定义一个事务时,BEGIN TRANSACTION 语句应与COMMITTRANSACTION 语句或ROLLBACK TRANSACTION 成对出现。在SQL Server中,事务定义语句可以嵌套,但实际上只有最外层的BEGINTRANSACTION 语句和COMMIT TRANSACTION 语句才能建立和提交事务;在回滚事务时,也只能使用最外层定义的事务名或存储点标记,而不能使用内层定义的事务名。事务嵌套常用在存储过程或触发器内,它们可以使用BEGINTRANSACTION…COMMIT TRANSACTION 对来相互调用。编写有效事务的建议

A、编写有效事务的指导原则

不要在事务处理期间输入数据

浏览数据时,尽量不要打开事务

保持事务尽可能的短

灵活地使用更低的事务隔离级别

 

在事务中尽量使访问的数据量最小

B、避免并发问题

为了防止并发问题,应该小心地管理隐性事务。在使用隐性事务时,COMMIT ROLLBACK 之后的下一个Transact-SQL语句会自动启动一个新事务。这可能在应用程序浏览数据时,甚至在要求用户输入时,打开新的事务。所以,在完成保护数据修改所需要的最后一个事务之后和再次需要一个事务来保护数据修改之前,应该关闭隐性事务。

事务处理DEMO 分析

DEMO1:使用事务的三种模式进行表的处理,分批执行,观察执行的过程。

use mydb

go

selecttimes=0,* from orders --检查当前表中的

--1SQL Server 首先于自管理模式

INSERTINTO orders

VALUES('p05','2011-09-10 00:00:00.000','ded','EN','4000',convert(varbinary(256),

pwdencrypt('passw0rd')))

selecttimes=1,* from orders �Cp05 被插入

go

--再次行此插入

INSERTINTO orders

VALUES('p05','2011-09-10 00:00:00.000','ded','EN','4000',convert(varbinary(256),

pwdencrypt('passw0rd')))

返回:

--消息2627级别14,状1,第1

--反了PRIMARY KEY 'PK_orders'。不能在'dbo.orders' 中插入重复键

--句已止。

selecttimes=2,* from orders �C-示数据没有

go

--2示事模式

BEGINTRANSACTION in_order --式事模式

INSERTINTO orders

VALUES('p06','2011-09-10 00:00:00.000','ded','EN','4000',convert(varbinary(256),

pwdencrypt('passw0rd')))

SELECTtimes=3,* FROM orders --'p06'被插入

ROLLBACKTRANSACTION in_order

GO

SELECTtimes=4,* FROM orders --为执行了回,插入的'p06'被撤消

--3式事模式

 


你可能感兴趣的:(信息,数据库操作,网上购物)