日期:2014-05-16  浏览次数:20529 次

SQL Server2008 事务和锁详解(MSSQL个人笔记之数据库优化之路 五)
--SQL Server2008 事务和锁详解(MSSQL个人笔记之数据库优化之路 五)    
    
/********************************************************************************    
 *主题:SQL Server2008 事务和锁详解     
 *说明:本文是个人学习的一些笔记和个人愚见    
 *      有很多地方你可能觉得有异议,欢迎一起讨论    
    
 *作者:Stephenzhou(阿蒙)    
 *日期: 2012.07.31    
 *Mail:szstephenzhou@163.com    
 *另外:转载请著名出处。    
**********************************************************************************/   

今天主要讲下锁,但是说到锁肯定就是要说到事务。

说到事务就要说下它的三个特性: 自动性,一致性,独立性,持久性。

事务的分类:自动提交事务,显式事务,隐式事务,批处理级事务。

在这里不做过多的介绍和说明,如有疑问可以留言。。

 

 --事务个数的查询
 select @@TRANCOUNT
 
 /*
-----------
0

(1 行受影响)*/

--save transaction  设置保存点 



use Erp_System 
go
begin transaction InsertTransl
save transaction A
delete consume_Shopid_Range where
 id='10010xxxxxxx1' 
 and Shopid=2 
 and GoodsId=6 
 and Amount =894 
 and ConsumeDate='2012-07-26 11:55:40.153'
 and mark='2FA4E2F3-DD8B-4ED3-8D9C-D7AE33BA5D0D'
 rollback transaction A
 insert into consume_Shopid_Range 
 (id,Shopid,GoodsId,Amount,ConsumeDate,mark)values
 ('10010xxxxxxx2',3,1,321,'2012-07-31 11:55:40.153','szstephenzhou')
 commit transaction  InsertTransl 
 go
  
/*(0 行受影响)

(1 行受影响)*/
--分析下上个结果:
--在上面的一个事务中,所限开始了一个事务 InsertTransl
--在这个事务中设置了保存的A
--然后删除一条记录 
--回顾到A点 也就是没有删除
--新增了一条记录
--commit提交事务InsertTransl




---Set xact_abort 语句 
/*
 *格式如下:
 *SET XACT_ABORT {ON|OFF}
 *当设置为 setxact_abort on 时,如果SQL语句出现运行错误,则数据库引擎将终止并回滚整个事务,
    即使前面能够正确的执行的SQL。
 *当设置成set xact_abort off 如果SQL错误的时候,数据库只回滚产生错误的sql语句。并且事务继续
    默认的情况是ON
*/
if OBJECT_ID('tb') is not null
drop table tb
go
create table tb(id int identity primary key ,name varchar(10))
 
 
 set xact_abort on 
 begin transaction insetran
 insert into tb values('stephen');
 insert into tb values('mrzhou');
 insert into tb values('stephen----------');
 insert into tb values('刘德华');
 insert into tb values('张学友');
 commit transaction insetran
 go
 /*
消息 208,级别 16,状态 1,第 3 行
对象名 'tb' 无效。

 */
 select * from tb
 /*
 id          name
----------- ----------

(0 行受影响)

 */
 set xact_abort off 
 begin transaction insetran
 insert into tb values('stephen');
 insert into tb values('mrzhou');
 insert into tb values('stephen----------');
 insert into tb values('刘德华');
 insert into tb values('张学友');
 commit transaction insetran
 go
 /*
(1 行受影响)

(1 行受影响)
消息 8152,级别 16,状态 14,第 4 行
将截断字符串或二进制数据。
语句已终止。

(1 行受影响)

(1 行受影响)
*/

select * from tb
/*id          name
----------- ----------
1           stephen
2           mrzhou
4           刘德华
5           张学友

(4 行受影响)
*/

--如上所述 当set xact_abort on 如果出现错误就会全部回滚 而设置成off的时候就只跳过错误继续执行。。

--但是如果设置成off的时候也是没办法执行跳过。这是为什么呢??

 set xact_abort off 
 begin transaction insetran
 insert into tb values('stephen');
 insert into tb values('mrzhou');
 insert into tb values(1,'stephen');
 insert into tb values('刘德华');
 insert into tb values('张学友');
 commit transaction insetran
 go
 
 /*
 消息 8101,级别 16,状态 1,第 5 行
仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'tb'中的标识列指定显式值。
 */
 --因为在这里是属于编译错误,在identity属性中不能插入数字。
 
 
 
 
 
 
 --在事务中有些语句是不能用的 如下
 /*
    *CREATE DATABASE
    *ALTER DATABASE
    *DROP DATABASE
    *RECONFIGURE
    *BACKUP
    *RESTORE
    *UPDATE STATISTICS
  
 */


 

 

 

 

 

 

锁机制

什么是锁,锁到底是个什么东西?有很多人都感觉是懂非懂的样子,了解了,好像是个什么东西。其实很简单 什么到底是什么呢?锁是一种规则。是用来控制同步

数据访问控制的一种机制。

打个比方吧,数据库中的锁就像交通信号灯。而车子就是每个事务。如果没有好好的控制红绿灯的话就会怎么样,当然是堵车了。如果没有控制好锁 同样会堵塞。

 

 

锁的定制

大家都知道,数据库的资源只由一个用户使用只要程序没问题,数据就不会出现不一致的情况。如果两个或者多个用户同时修改就有可能出现并发冲突导致如下错误:

 

更新丢失<