站长资源数据库

sqlserver中的事务和锁详细解析

整理:jimmy2024/12/28浏览2
简介前几天“拜读”《sqlserver2005高级程序设计》和《SQL Server 2008编程入门经典(第3版)》这两本翻译后的中文版书籍。竟然发现目录结构大致一样,其讲解的内容几乎差不多。有抄袭的嫌疑。看到“事务和锁”那一张中,发现连举的小例子、表格都一模一样。哈哈。。。对这类书籍,真不想做太多评

前几天“拜读”《sqlserver2005高级程序设计》和《SQL Server 2008编程入门经典(第3版)》这两本翻译后的中文版书籍。竟然发现目录结构大致一样,其讲解的内容几乎差不多。有抄袭的嫌疑。看到“事务和锁”那一张中,发现连举的小例子、表格都一模一样。哈哈。。。对这类书籍,真不想做太多评论了。国内那些翻译版的书籍嘛。说真的,大部分翻译得有点生硬。而那些“原创著作”嘛。大多是相互抄袭,空谈。就微软技术体系而言,如果直接从MSDN或者联机丛书中copy一下,再随便贴几页的代码,那样就能出版销售,那可能我也能著书了,因为那确实没啥水平。

当然,也不乏精品之作,只是很少且很难找到罢了。好了,言归正传,开始说说事务和锁,这大概是数据库中比较难理解的东西了。


一、脏读、不可重复读、幻读

(1)脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

例如:

张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。

与此同时,

事务B正在读取张三的工资,读取到张三的工资为8000。

随后,

事务A发生异常,而回滚了事务。张三的工资又回滚为5000。

最后,

事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。

(2)不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

例如:

在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。

与此同时,

事务B把张三的工资改为8000,并提交了事务。

随后,

在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。

(3)幻读: 是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

例如:

目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。

此时,

事务B插入一条工资也为5000的记录。

这是,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。

不可重复读的重点是修改:
同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除:
同样的条件,第 1 次和第 2 次读出来的记录数不一样

二、独占锁、共享锁、更新锁,乐观锁、悲观锁

1、锁的两种分类方式

(1)从数据库系统的角度来看,锁分为以下三种类型:

"BACKGROUND-COLOR: #ffff99">"BACKGROUND-COLOR: #ffff99">三、事务五种隔离级别

Isolation 属性一共支持五种事务设置,具体介绍如下:

(1)DEFAULT

使用数据库设置的隔离级别(默认),由DBA 默认的设置来决定隔离级别。

(2)READ_UNCOMMITTED

这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。

会出现脏读、不可重复读、幻读 (隔离级别最低,并发性能高)。

(3)READ_COMMITTED

保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。

可以避免脏读,但会出现不可重复读、幻读问题(锁定正在读取的行)。

(4)REPEATABLE_READ

可以防止脏读、不可重复读,但会出幻读(锁定所读取的所有行)。

(5)SERIALIZABLE

这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。

保证所有的情况不会发生(锁表)。