事务全攻略[转]

 

None.gif 关于事务
None.gif
None.gif一  事务的属性  
None.gif 
None.gif事务具有ACID属性 : 
None.gif即  Atomic原子性,  Consistent一致性,  Isolated隔离性,  Durable永久性  
None.gif 
None.gif
1 ,原子性:  就是事务应作为一个工作单元,事务处理完成,所有的工作要么都在数据库中保存下来,要么完全  
None.gif回滚,全部不保留  
None.gif 
None.gif 
None.gif
2 ,一致性 :事务完成或者撤销后,都应该处于一致的状态  
None.gif 
None.gif
3 ,隔离性: 
None.gif     多个事务同时进行,它们之间应该互不干扰.应该防止一个事务处理其他事务也要修改的数据时,  
None.gif不合理的存取和不完整的读取数据  
None.gif 
None.gif 
None.gif
4 ,永久性 : 
None.gif     事务提交以后,所做的工作就被永久的保存下来  
None.gif 
None.gif 
None.gif二  事务并发处理会产生的问题    
None.gif 
None.gif
1 ,丢失更新  
None.gif     当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题、  
None.gif每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。  
None.gif 
None.gif
2 ,脏读  
None.gif     当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。  
None.gif     第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。  
None.gif 
None.gif
3 ,不可重复读  
None.gif      当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。  
None.gif      不一致的分析与未确认的相关性类似,因为其它事务也是正在更改第二个事务正在读取的数据。  
None.gif      然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其它事务更改;因而该行被非重复读取。  
None.gif 
None.gif
4 ,幻像读  
None.gif      当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。  
None.gif      事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。  
None.gif 
None.gif 
None.gif三  事务处理类型  
None.gif 
None.gif 
None.gif
1 ,自动处理事务  
None.gif      系统默认每个T-SQL命令都是事务处理    由系统自动开始并提交  
None.gif 
None.gif 
None.gif
2 ,隐式事务  
None.gif      当有大量的DDL  和DML命令执行时会自动开始,并一直保持到用户明确提交为止,切换隐式事务可以用SET  IMPLICIT_TRANSACTIONS  
None.gif      为连接设置隐性事务模式.当设置为  
ON   时, SET   IMPLICIT_TRANSACTIONS  将连接设置为隐性事务模式。当设置为   OFF   时,则使连接返回到自动提交事务模式  
None.gif 
None.gif 
None.gif
3 ,用户定义事务  
None.gif      由用户来控制事务的开始和结束    命令有:  
begin    tran    commit    tran      rollback    tran   命令  
None.gif 
None.gif 
None.gif
4 ,分布式事务  
None.gif      跨越多个服务器的事务称为分布式事务,sql  server  可以由DTc  microsoft  
distributed    transaction   coordinator  
None.gif      来支持处理分布式事务,可以使用  
BEgin    distributed    transaction   命令启动一个分布式事务处理  
None.gif 
None.gif 
None.gif 
None.gif四    事务处理的隔离级别  
None.gif      使用SET  
TRANSACTION    ISOLATION   LEVEL来控制由连接发出的所有语句的默认事务锁定行为从低到高
None.gif依次是 
READ    UNCOMMITTED   
None.gif 
None.gif执行脏读或 
0  级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置  NOLOCK  相同。这是四个隔离级别中限制最小的级别。  
None.gif 
None.gif举例  
None.gif 
None.gif设table1(A,B,C)  
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gif 
None.gif新建两个连接  
None.gif在第一个连接中执行以下语句  
None.gif
select    *    from   table1  
None.gif
begin    tran   
None.gif
update   table1   set   c = ' c '   
None.gif
select    *    from   table1  
None.gif
waitfor   delay   ' 00:00:10 '      -- 等待10秒  
None.gif
rollback    tran   
None.gif
select    *    from   table1  
None.gif 
None.gif在第二个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    READ    UNCOMMITTED   
None.gif
print    ' 脏读 '   
None.gif
select    *    from   table1  
None.gif
if    @@rowcount > 0   
None.gif
begin   
None.gif 
waitfor   delay   ' 00:00:10 '     
None.gif 
print    ' 不重复读 '   
None.gif 
select    *    from   table1  
None.gif
end   
None.gif 
None.gif第二个连接的结果  
None.gif 
None.gif脏读  
None.gifA        B        C  
None.gifa1      b1      c  
None.gifa2      b2      c  
None.gifa3      b3      c  
None.gif 
None.gif
' 不重复读 '   
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gif 
None.gif 
None.gif 
None.gif
READ    COMMITTED   
None.gif 
None.gif指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是  SQL  Server  的默认值。  
None.gif 
None.gif 
None.gif在第一个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    READ    COMMITTED   
None.gif
begin    tran   
None.gif
print    ' 初始 '   
None.gif
select    *    from   table1  
None.gif
waitfor   delay   ' 00:00:10 '      -- 等待10秒  
None.gif
print    ' 不重复读 '   
None.gif
select    *    from   table1  
None.gif
rollback    tran   
None.gif 
None.gif 
None.gif在第二个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    READ    COMMITTED   
None.gif 
None.gif
update   table1   set   c = ' c '   
None.gif     
None.gif 
None.gif第一个连接的结果  
None.gif 
None.gif初始  
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gif 
None.gif不重复读  
None.gifA        B        C  
None.gifa1      b1      c  
None.gifa2      b2      c  
None.gifa3      b3      c  
None.gif 
None.gif 
None.gif 
None.gif
REPEATABLE    READ   
None.gif 
None.gif锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。  
None.gif 
None.gif 
None.gif在第一个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    REPEATABLE    READ   
None.gif
begin    tran   
None.gif
print    ' 初始 '   
None.gif
select    *    from   table1  
None.gif
waitfor   delay   ' 00:00:10 '      -- 等待10秒  
None.gif
print    ' 幻像读 '   
None.gif
select    *    from   table1  
None.gif
rollback    tran   
None.gif 
None.gif 
None.gif在第二个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    REPEATABLE    READ   
None.gif
insert     table1   select    ' a4 ' , ' b4 ' , ' c4 '   
None.gif 
None.gif 
None.gif第一个连接的结果  
None.gif 
None.gif初始  
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gif 
None.gif幻像读  
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gifa4      b4      c4  
None.gif 
None.gif 
None.gif
SERIALIZABLE   
None.gif 
None.gif在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有  
SELECT   语句中的所有表上设置   HOLDLOCK   相同。  
None.gif 
None.gif 
None.gif在第一个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    SERIALIZABLE   
None.gif
begin    tran   
None.gif
print    ' 初始 '   
None.gif
select    *    from   table1  
None.gif
waitfor   delay   ' 00:00:10 '      -- 等待10秒  
None.gif
print    ' 没有变化 '   
None.gif
select    *    from   table1  
None.gif
rollback    tran   
None.gif 
None.gif 
None.gif在第二个连接中执行以下语句  
None.gif
SET    TRANSACTION    ISOLATION    LEVEL    SERIALIZABLE   
None.gif
insert     table1   select    ' a4 ' , ' b4 ' , ' c4 '   
None.gif 
None.gif 
None.gif第一个连接的结果  
None.gif 
None.gif初始  
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gif 
None.gif没有变化  
None.gifA        B        C  
None.gifa1      b1      c1  
None.gifa2      b2      c2  
None.gifa3      b3      c3  
None.gif 
None.gif 
None.gif五  事务处理嵌套的语法和对
@@TRANCOUNT的影响   
None.gif 
None.gif
BEGIN    TRAN      @@TRANCOUNT 1   
None.gif
COMMIT    TRAN    @@TRANCOUNT 1   
None.gif
ROLLBACK   TR  
None.gif
None.gif 
None.gif
None.gif 
None.gif
None.gif 
None.gif
None.gifsp_lock2
None.gifVersion: SQL Server 
7.0 / 2000
None.gifCreated 
by : Alexander Chigrik
None.gifhttp:
// www.MSSQLCity.com /   -   all  about MS SQL
None.gif(SQL Server Articles, FAQ, Scripts, Tips 
and  Test Exams). 
None.gif
None.gifThis stored 
procedure  can be used instead  of  sp_lock system stored  procedure
None.gif
to   return  more detailed locking  view  (it can  return   user  name, host name,
None.gif
database  name, object name,  index  name  and  object owner).
None.gifThis 
is  the example  to   use  sp_lock2:
None.gif
None.gif
EXEC  sp_lock2
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gifVersion: SQL Server 7.0/2000
InBlock.gifCreated by: Alexander Chigrik
InBlock.gifhttp://www.MSSQLCity.com/ - all about MS SQL
InBlock.gif(SQL Server Articles, FAQ, Scripts, Tips and Test Exams).
InBlock.gif
InBlock.gifThis stored procedure can be used instead of sp_lock stored procedure
InBlock.gifto return more detailed locking view (it can return user name, host name,
InBlock.gifdatabase name, object name, index name and object owner).
InBlock.gifThis is the example to use sp_lock2:
InBlock.gif
InBlock.gifEXEC sp_lock2
ExpandedBlockEnd.gif
*/

None.gif
None.gif
USE  MASTER
None.gif
GO
None.gif
IF   OBJECT_ID ( ' sp_lock2 ' IS   NOT   NULL   DROP   PROC  sp_lock2
None.gif
GO
None.gif
CREATE   PROCEDURE  sp_lock2
ExpandedBlockStart.gifContractedBlock.gif
@spid1   int   =   NULL ,       /**/ /* server process id to check for locks */
ExpandedBlockStart.gifContractedBlock.gif
@spid2   int   =   NULL         /**/ /* other process id to check for locks */
None.gif
as
None.gif
None.gif
set  nocount  on
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gif** Show the locks for both parameters.
ExpandedBlockEnd.gif
*/

None.gif
declare   @objid   int ,
None.gif   
@indid   int ,
None.gif   
@dbid   int ,
None.gif   
@string   Nvarchar ( 255 )
None.gif
None.gif
CREATE   TABLE  #locktable
None.gif   (
None.gif   spid       
smallint
None.gif   ,loginname 
nvarchar ( 20 )
None.gif   ,hostname  
nvarchar ( 30 )
None.gif   ,dbid      
int
None.gif   ,dbname    
nvarchar ( 20 )
None.gif   ,ObjOwner  
nvarchar ( 128 )
None.gif   ,objId     
int
None.gif   ,ObjName   
nvarchar ( 128 )
None.gif   ,IndId     
int
None.gif   ,IndName   
nvarchar ( 128 )
None.gif   ,Type      
nvarchar ( 4 )
None.gif   ,Resource  
nvarchar ( 16 )
None.gif   ,Mode      
nvarchar ( 8 )
None.gif   ,Status    
nvarchar ( 5 )
None.gif   )
None.gif
None.gif
if   @spid1   is   not   NULL
None.gif
begin
None.gif   
INSERT  #locktable
None.gif      (
None.gif      spid
None.gif      ,loginname
None.gif      ,hostname
None.gif      ,dbid
None.gif      ,dbname
None.gif      ,ObjOwner
None.gif      ,objId
None.gif      ,ObjName
None.gif      ,IndId
None.gif      ,IndName
None.gif      ,Type
None.gif      ,Resource
None.gif      ,Mode
None.gif      ,Status
None.gif      )
None.gif   
select   convert  ( smallint , l.req_spid)
None.gif      ,
coalesce ( substring  (s.loginame,  1 20 ), '' )
None.gif      ,
coalesce ( substring  (s.hostname,  1 30 ), '' )
None.gif      ,l.rsc_dbid
None.gif      ,
substring  ( db_name (l.rsc_dbid),  1 20 )
None.gif      ,
''
None.gif      ,l.rsc_objid
None.gif      ,
''
None.gif      ,l.rsc_indid
None.gif      ,
''
None.gif      ,
substring  (v.name,  1 4 )
None.gif      ,
substring  (l.rsc_text,  1 16 )
None.gif      ,
substring  (u.name,  1 8 )
None.gif      ,
substring  (x.name,  1 5 )
None.gif   
from  master.dbo.syslockinfo l,
None.gif      master.dbo.spt_values v,
None.gif      master.dbo.spt_values x,
None.gif      master.dbo.spt_values u,
None.gif      master.dbo.sysprocesses s
None.gif   
where  l.rsc_type  =  v. number
None.gif   
and    v.type  =   ' LR '
None.gif   
and    l.req_status  =  x. number
None.gif   
and    x.type  =   ' LS '
None.gif   
and    l.req_mode  +   1   =  u. number
None.gif   
and    u.type  =   ' L '
None.gif   
and    req_spid  in  ( @spid1 @spid2 )
None.gif   
and    req_spid  =  s.spid
None.gif
end
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*
InBlock.gif** No parameters, so show all the locks.
ExpandedBlockEnd.gif
*/

None.gif
else
None.gif
begin
None.gif   
INSERT  #locktable
None.gif      (
None.gif      spid
None.gif      ,loginname
None.gif      ,hostname
None.gif      ,dbid
None.gif      ,dbname
None.gif      ,ObjOwner
None.gif      ,objId
None.gif      ,ObjName
None.gif      ,IndId
None.gif      ,IndName
None.gif      ,Type
None.gif      ,Resource
None.gif      ,Mode
None.gif      ,Status
None.gif      )
None.gif   
select   convert  ( smallint , l.req_spid)
None.gif      ,
coalesce ( substring  (s.loginame,  1 20 ), '' )
None.gif      ,
coalesce ( substring  (s.hostname,  1 30 ), '' )
None.gif      ,l.rsc_dbid
None.gif      ,
substring  ( db_name (l.rsc_dbid),  1 20 )
None.gif      ,
''
None.gif      ,l.rsc_objid
None.gif      ,
''
None.gif      ,l.rsc_indid
None.gif      ,
''
None.gif      ,
substring  (v.name,  1 4 )
None.gif      ,
substring  (l.rsc_text,  1 16 )
None.gif      ,
substring  (u.name,  1 8 )
None.gif      ,
substring  (x.name,  1 5 )
None.gif   
from  master.dbo.syslockinfo l,
None.gif      master.dbo.spt_values v,
None.gif      master.dbo.spt_values x,
None.gif      master.dbo.spt_values u,
None.gif      master.dbo.sysprocesses s
None.gif   
where  l.rsc_type  =  v. number
None.gif   
and    v.type  =   ' LR '
None.gif   
and    l.req_status  =  x. number
None.gif   
and    x.type  =   ' LS '
None.gif   
and    l.req_mode  +   1   =  u. number
None.gif   
and    u.type  =   ' L '
None.gif   
and    req_spid  =  s.spid
None.gif   
order   by  spID
None.gif
END
None.gif
DECLARE  lock_cursor  CURSOR
None.gif
FOR   SELECT  dbid, ObjId, IndId  FROM  #locktable
None.gif  
WHERE  Type  <> ' DB '   and  Type  <>   ' FIL '
None.gif
None.gif
OPEN  lock_cursor
None.gif
FETCH   NEXT   FROM  lock_cursor  INTO   @dbid @ObjId @IndId
None.gif
WHILE   @@FETCH_STATUS   =   0
None.gif   
BEGIN
None.gif
None.gif   
SELECT   @string   =
None.gif      
' USE  '   +   db_name ( @dbid +   char ( 13 )
None.gif      
+   ' update #locktable set ObjName = name, ObjOwner = USER_NAME(uid) '
None.gif      
+   '  from sysobjects where id =  '   +   convert ( varchar ( 32 ), @objid )
None.gif      
+   '  and ObjId =  '   +   convert ( varchar ( 32 ), @objid )
None.gif      
+   '  and dbid =  '   +   convert ( varchar ( 32 ), @dbId )
None.gif
None.gif   
EXECUTE  ( @string )
None.gif
None.gif   
SELECT   @string   =
None.gif      
' USE  '   +   db_name ( @dbid +   char ( 13 )
None.gif      
+   ' update #locktable set IndName = i.name from sysindexes i  '
None.gif      
+   '  where i.id =  '   +   convert ( varchar ( 32 ), @objid )
None.gif      
+   '  and i.indid =  '   +   convert ( varchar ( 32 ), @indid )
None.gif      
+   '  and ObjId =  '   +   convert ( varchar ( 32 ), @objid )
None.gif      
+   '  and dbid =  '   +   convert ( varchar ( 32 ), @dbId )
None.gif      
+   '  and #locktable.indid =  '   +   convert ( varchar ( 32 ), @indid )
None.gif
None.gif   
EXECUTE  ( @string )
None.gif
None.gif   
FETCH   NEXT   FROM  lock_cursor  INTO   @dbid @ObjId @IndId
None.gif   
END
None.gif
CLOSE  lock_cursor
None.gif
DEALLOCATE  lock_cursor
None.gif
None.gif
SELECT   *   FROM  #locktable
None.gif
return  ( 0 )
None.gif
--  END sp_lock2
None.gif
GO

转载于:https://www.cnblogs.com/fxwdl/archive/2007/03/15/676097.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值