事务(Transaction)是保证一系列操作数据可以正确完成,保证数据的完整性。锁(Lock)保证数据操作过程中不会受到任何其祂影响。
事务是作为单个逻辑工作单元执行的一系列工作,必须有四个属性。
一、原子性:事务必须是原子性的工作单元,要么全执行、要不全都不执行。
二、一致性:事务完成时必须保持数据一致状态。
三、隔离性:由并发事务所作的修改必须与其它并发的事务所作的修改隔离。由于事务在开始时就会识别数据所处的状态,以便发生错误时可以回滚操作,所以另一个并发事务要么修改在它之前的状态,要么修改在它之后的状态,不能在事务处理过程时修改它的状态。这也称为可串行性。
四、执久性:事务完成后,其操作结果对于系统的影响是永久的。
例:
----开始事务
BENGIN TRAN
----定义参数
DECLARE @订单ID int
-----添加一个订单
INSERT 订单(要添加的表名)
(字段)
VALUES
(值)
If @@ERROR>0
GOTO TranRoolBack
SET @订单ID=@@IDENTITY
------添加两个订单详情
INSERT 订单明细(要添加的表名)
(字段)
VALUES
(值)
If @@ERROR>0
GOTO TranRoolBack
TranRoolBack:
IF @@ERROR>0 OR @@ROWCOUNT<>1
ROLLBACK TRAN
ELSE
COMMIT TRAN
GO
事务是以“BEGIN TRAN”语句开头,以“ROLLBACK TRAN”或“COMMIT TRAN”语句结束
注意事项:
1、在每个操作之后,都要检查一下@@ERROR和@@ROWCOUNT的值。@@ERROR只对当前操作有效,当进行第二个操作时就会被第二个操作取代。@@ROWCOUNT是判断当前操作影响了多少条记录。如果在执行UPDATE和DELETE时,没有符合记录时,@@ERROR为0,因此还要检查@@ROWCOUNT的值,以确定操作是否成功
2、当执行事务结束后,其后的代码还可执行,但出错后不会进行回滚。
3、操作完成的记录下式写入数据,此时也不能进行回滚
4、在事务执行时,发生意外终断事务,则操作会进行回滚
5、无法回滚的语句不能在事务中使用。如
Creat database、Alert database、Drop database、Load database、Restore database、Backup log、Restore log、Load transaction、Dump transaction、Disk init、Reconfigure、Update statistics
工作原理:
事务开始时,SQL SERVER就会将要修改的数据锁定,同时创建一个临时的事务日志,在该临时的事务日志里存放更改的数据和更必的过程。
在事务末提交时,事务中所有的数据操作都是临时的,一旦发生数据操作失败,就使用临时日志中的数据去回滚操作,并解除锁定。如果事务成功提交后,数据库就将临时事务日志清除,此时事务操作完成。
事务执行模式:
1、显式事务:以“BEGIN TRAN”语句开始,以“COMMIT TRAN”或“ROLLBACK TRAN”结束的事务。
2、自动提交事务:如我们做的DELETE CREATE UPDATE等
3、隐式事务:当执行“SET IMPLICIT_TRANSACTIONS ON”语句后,隐式事务是一个连续的事务链。只有执行“SET IMPLICIT_TRANSACTIONS OFF”语句后才结束这种隐式事务的模式。以下任务一个语句都会自动启动事务
Alter table Create Open Insert Select Update Delete
Drop Truncate table Fetch Grant Revoke
编写事务的原则:(主要还是减少资源的占用)
一、事务要尽可能简短
二、在事务中访问的数据量要尽量最少:由于事务处理会锁定记录,访问的数据越少锁定的行数也越少,这样事务之间的争夺就越少。
三、浏览数据时尽量不要打开事务
四、在事务处理期间昼不要请求用户输入:在事务处理过程中,如果还要等待用户输入,事务占用的所有资源都会保留相当长时间,有可能会造成阻塞问题。
嵌套事务注意事项:
虽然事务支持嵌套,但是事务的嵌套与其它的嵌套方式有些不同。嵌套事务并不是将嵌套的语句执行完毕,嵌套事务会忽略内层事务的COMMIT,只提交外层事务的COMMIT语句。虽然内层的COMMIT不能执行,但不可省略。内层ROLLBACK语句仍然有效,但不可回滚到本层之前或之后的状态
嵌套的层次:
SQL SERVER2005中提供了全局变量@@TRANCOUNT来计算目前事务嵌套的层次,在T-SQL语句中遇到一个“BEGIN TRAN”则@@TRANCOUNT自动加一,每遇到一个“COMMIT TRAN”时会减一,遇到“ROLLBACK TRAN”则清零。
事务的保存点:
内层嵌套事务回滚时,并不会回滚到祂的事务开始状态,而回滚到外层事务的开始状态。所以我们要用一个事务保存点来主事务回滚到保存点时的状态。
SAVE{TRAN | TRANSACTION}{savepoint_name| @savepoint_variable}
Savepoint_name为保存点名称,@savepoint_Variable为保存点名称的变量。
在设置保存点后,可以事务回滚到某一个保存点,回滚方式为:
ROLLBACK{TRAN|REANSACTION}{savepoint_name| @savepoint_variable}
如:
Select *from 产品
Begin Tran
Insert 产品()values()
If @@ERROR>0 OR @@ROWCOUNT<>1
GOTO TRANROLLBACK
Insert 产品()values()
If @@ERROR>0 OR @@ROWCOUNT<>1
GOTO TRANROLLBACK
---添加保存点
Save Tran 保存点名称
Select *from 产品
--嵌套事务
Begion Tran
If @@ERROR>0 OR @@ROWCOUNT<>1
ROLLBACK TRAN
Else
COMMIT TRAN
--嵌套事务结束
Select *from 产品
Insert 产品()values()
If @@ERROR>0 OR @@ROWCOUNT<>1
ROLLBACK TRAN
Else
COMMIT TRAN
Select *from 产品
If @@ERROR>0 OR @@ROWCOUNT<>1
ROLLBACK TRAN
Else
COMMIT TRAN
在嵌套事务回滚后,事务会在保存点接着执行后面的事务。