您的位置:首页 > 数据库

SQL Server 2005系列教学(17) 事务

2008-06-08 13:21 295 查看
事务在数据库中应该是很重要的一个概念。在这里只是简单介绍.详细内容会在数据库实践课中介绍

在使用DELETE和UPDATE命令对数据库进行更新时,一次只能操作一个表,这就带来数据库的数据不一致的问题。先修改一个表然后再修改另一个表,但就在你对一个表操作之后,在另一个操作之前会产生一个数据停滞的问题。例如企业取消了后勤部,需要将后勤部从部门表中删除,要修部门表,而员工表中的后勤部的员工怎么办,也应该删除。因此,这两个表都需要修改,这种修改只能通过两条DELETE语句进行。假设后勤部编号为‘1012’
第一条DELETE语句修改部门表
DELETE FROM 部门表 where 部门编号=‘1012’
第二条DELETE语句修改员工表
Delete from 员工表 where 部门编号=’1012’
如果第一条语句执行了,第二条还没有执行,会出现什么情况?
但此时部门表中还仍然有后勤部的员工存在,这就是数据的不一致!只有执行完第二个DELETE语句之后,数据才重新处于一致状态。但是如果执行完第一条语句后,计算机突然出现故障,网络出现故障,或数据库有问题,无法再继续执行第二条DELETE语句,则数据库中的数据将处于一个永远不一致的状态。因此必须保证这两条DELETE语句同时执行。为解决类似的问题,数据库系统通常都引入了事务transaction的概念。通过事务来解决数据不一致的问题。用来保证数据库的完整性,保证一系列的数据操作可以全部正确完成,不会造成数据操作到一半未完成。

常用的事务处理语句包括:
COMMIT WORK:把当前事务所作的更改永久化(写入磁盘)即成功生效
ROLLBACK:作废上次提交以来的所有更改,也就是说这次事务失效,不成功。

事务:指作为单个逻辑工作单元执行的一系列操作,而这些逻辑工作单元需要具有原子性,一致性,隔离性和持久性四个属性。统称为ACID属性。

原子性:指事务必须是原子工作单元,不可分隔性,即对于事务所进行数据修改,要么全部执行,要么全都不执行。
一致性:指事务在完成时,必须使所有的数据都保持一致性状态,而且在相关数据库中,所有规则都必须应用于事务的修改。以保持所有数据的完整性。
也就是说,如果有多个表中放有一个人的信息,那如果你要修改这个人的信息,就必须多个表中的信息都要修改,不能有的修改,有的不修改。
隔离性:指由并发事务所做的修改必须与任何其他并发事务所做的修改相隔离。事务查看数据时数据所处的状态,要么是被另一并发事务修改之前的状态,要么是被另一事务修改之后的状态,即事务不会查看正在由另一个并发事务正在修改的数据。
持久性:指事务完成之后,它对于系统的影响是永久性的,即使系统出现故障也是如此。比如说,我们把一个人的记录放在磁盘上这后,停电了,这个人的记录已经存在磁盘上了,不可能来电以后又没有了。!

事务的类型:隐式事务和显式事务
隐式事务:每次执行SQL Server 的任何数据修改语句时,它都是一个隐式事务。例如:下列SQL语句是一个独立事务:也就是咱们所说的三种基本操作。
Insert table values (1,’abc’)
Update table set coll=5 where coll=1
Delete from table1 where coll=5
Go
首先来看一下INSERT语句,如果这个记录有10个字段,如果我把一条记录插入到数据库中,那么这条记录各个字段都有其值,都有自己应该得到的值,那怕是空值!总之都会有一个值,不会出现这么一种情况。我有三个字段已经赋值了,其他的字段我还没有来的及赋值,或者是出错了,但该记录也被插入进去了。
这其实也就是一个事务,不是所有字段都合法我就不会把这个记录插入到相应的数据表中。
那为什么叫隐式事务呢,因为我们并没有规定什么时候是事务的开始,什么时候是事务的结束。
那么还有一种叫显式事务。显式事务是在程序中用BEGIN TRANSACTION 命令来标识一个事务的开始,用COMMIT TRANSACTION命令标识事务结束;这两个命令之间的所有语句被视为一体。只有执行到COMMIT TRANSACTION命令时,事务中对数据库的更新操作才算确认。和BEGIN。。。。END 命令类似。这两个命令也可以进行嵌套,即事务可以嵌套执行。
通过咱们所介绍的,你也可以看,如何判断一个事务是隐式事务还是显式事务。也就是看一下有没有BEGIN TRANSACTION 语句
还有就是INSERT ,UPDATE,DELETE是系统自带的隐式事务。
如果是显式事务的话,BEGIN TRANSACTION 和COMMIT TRANSACTION之间的语句要么全部执行要不就一条也不执行。当然,
下面我们来看一下begin transaction的语法:
Begin transaction transaction_name |@tran_name_var
Commit transaction的语法:
Commit transaction transaction_name|@tran_name_var
可以用变量来指定事务的名称,只能是字符型。
Begin transaction 可以缩写为 begin tran
Commit transaction 可以缩写为 commit tran 或 commit
注意:名称,系统只能识别前32个字符!
我们来看一个具体的例子:
这里咱们就把刚才删除后勤部的例子讲一下:

declare @transaction_name varchar(32)
set @transaction_name='my_transaction'
begin transaction @transaction_name
delete from 部门表 where 部门编号='1003'

delete from 员工表 wher 部门编号='1012'
故意写错一个,如果正确就可以错误!
commit transaction
go

select @@error

select * from 部门表
select * from 员工表

我这两条DELETE语句要不同时执行要不就都不执行。如果第一行执行了,第二条还没有执行,突然系统出现故障,那么数据库会回滚到更改之前的状态。
如果不是嵌套的话,事务名称不是必须的。
1001 人事部 1234565
1002 教学部 21323234
1003 后勤部 2323111
1 1001 贾宁 男 26
2 1002 霍玉娟 女 24
3 1003 李逍遥 男 36
4 1002 赵灵儿 女 32
5 1001 张李 男 28
6 1002 ABCDEF 女 25
7 1002 李春明 男 27
8 1001 aa NULL NULL
9 1003 杜飞 男 29
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息