什么是事务会锁表吗?什么是锁

2009年8月 MS-SQL Server大版内专家分月排行榜第一2009年7月 MS-SQL Server大版内专家分月排行榜第一
2010年8月 其他数据库开发大版内专家分月排行榜第二
2009年8月 MS-SQL Server大版内专家分月排行榜第一2009年7月 MS-SQL Server大版内专家分月排行榜第一
2010年8月 其他数据库开发大版内专家分月排行榜第二
2009年8月 MS-SQL Server大版内专家分月排行榜第一2009年7月 MS-SQL Server大版内专家分月排行榜第一
2010年8月 其他数据库开发大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。数据库(13)
阅读本文前建议先对事务有过基本的了解,有使用过事务,听过“锁”这个概念,希望快速了解这些概念并应用到实际开发中去。
对于事务和锁的详细解说可以参考中的事务和锁系列,本文只是试图用最简单的语言(甚至不太精准)来帮助初学者理解锁和事务的概念。若要更加精准、全面和深入的概念请自行阅读相关资料。
什么?你说你没用过事务?没用过锁?
其实你一直在用,数据库已经默认在使用了,只是你没感觉到而已。
其实默认情况下,你的每一个增删改查,修改数据库对象,数据库都会自动使用使用事务,同时就用到了锁,数据库会根据你的操作自动使用不同的锁。数据库默认使用“提交读”级别的隔离级别。
下面先讲锁。
操作资源时先锁住资源。锁的作用是隔离数据库的操作,防止并发访问下的数据错乱(具体有哪些错乱请参见)。
也就是说,在操作资源时,不准其他人来捣乱,要把其他人隔离到一边等着。
上面讲的“操作&包括增,删,改,查,修改对象等操作。
我们在做不同的操作时,数据库会自动使用锁,先锁住资源。针对不同的访问可以有不同的锁。
以下是几项最基本的锁(详情请参见MSDN:锁定 [SQL Server], 模式)。
1、&& 读取数据时的“共享锁”。
在读数据时,若还没读完,其他人不要来修改数据,但其他人可以一起读数据。
2、&& 更新数据时用“更新锁”。
其实更新数据分为两个过程,第一个过程是读取待修改的行,第二个过程是正式修改数据。
在更新数据时,可以想象有很多行数据要一行一行修改,若还全部没修改完,其他人就不要来读数据,因为读到的数据也是不完整的,除非明确指示愿意读这些脏数据(使用with(nolock)提示);同时其他人绝对不允许中途改数据,至少等我改完了再来改。另外,在更新数据时,表结构也不能改,要是把我要更改的字段都删掉了那我还改什么!要么在我操作前就删除,要么等我操作以后再删。
3、&& 删除与插入数据时会有“排它锁”.
类似于更新数据,在删除和插入期间,不允许别人来读数据,,除非你明确指示愿意读这些脏数据(使用with(nolock)提示。同时,不管你愿不愿意,都绝对不允许来中途改我的数据。要等我全部改完了其他才能操作。
4、&& 修改视图,函数等数据对象时会有“架构锁”
修改数据库架构时也不允许其他人来操作。比如我正在删除一个表,你还想来读这个表的数据?明显不可能。
5、&& 上述锁在真正生效前还会有“意向锁”,就是锁资源前先发布声明:“我要锁资源了,其他人在外边等着,不要强行进来和我抢资源!”,意向锁可以和前面的基本锁进行组合。意向锁的好处当然就是事先通知其他人,免得其他人强行闯进来抢资源,再被暴力赶出去,因为这种“强行抢”和“暴力赶”的成本不低。
锁针对的是数据库资源,哪些资源会被数据库“锁”呢?最基本的有数据行,数据页,数据表,数据文件,甚至整个数据库(详情请参见MSDN:锁定 [SQL Server], 可锁定资源)。
上面讲完了各种基本锁的基础概念,大概对锁有了一个了解,那在我们实际的开发过程中如何使用呢?光看猪跑不吃猪肉没意思吧?
前面已经说到数据库会自动使用锁,而实际上我们可以用一些提示信息(参见MSDN:表提示)指示在一条SQL语句中,数据库使用哪种锁,但是需要事先声明的是,提示终归只是提示,你无法强制数据库做不符合数据规则的事。
Select * from table with(nolock)
不管别人怎么锁住了数据,我都要读出来。但写数据的锁定规则不变。
Select * from table with(HoldLock)
Select * from table with(UpdLock)
Select * from table with(ReadPast)
Select * from table with(XLock)
接下来讲事务。
简单来说,在使用过程中,事务就是把许多SQL语句打包成一个整体执行,这些语句要么全部成功,要么全部失败。
当然,上面这句只描述了事务的“原子性”(为什么叫“原子”?原子在化学反应中被认为是不可再分割的最小单位),事实上事务还有其他特性(一致性,隔离性,持久性),这里重点讲隔离性。
前面讲锁的时候就提到了“隔离”,那事务的隔离与锁的隔离有什么区别呢?(专家们不要笑,这问题曾经困扰了我许久,概念太多,很绕的)
事实上事务的隔离就是锁的隔离,事务的隔离是通过锁来实现的,事务只是可以设置隔离的级别,而不同的隔离级别只是控制了锁的粒度(可以暂时粗暴地把“粒度”一词理解为“力度”或“级别”),或者说,发生事务时使用什么锁,锁什么资源,锁多久(这个说法不是完全地精准,但可先粗略地这样理解)。
事务有以下几种基本的隔离级别(详情请参见MSDN:锁定 [SQL Server], 隔离级别)
锁住的资源
不能解决的问题
别的事务还未更新完数据你就能直接读出来,脏读
仅读取的行
访问完就释放
你刚读取完数据行,再读时,原来行中的数据就不一样了,这叫不可重复读
仅读取的行
到事务结束
你刚读取完数据行,尽管原来读到的数据不会改,但再读时就可能多了新行了(不会少行哦!),这叫幻像读。
整个SQL语句可能涉及的范围,包括后面插入的行。
到事务结束
所有问题都解决了,不会有脏读,不可重复读和幻像读
在上面表中你或许已经发现了一些问题。
1、& 每一个隔离级别都是解决上一个隔离级别中未能解决的问题。
2、& 不同的隔离级别都只是“共享锁”,也就是说只影响读数据?
答:是的,如你所见。隔离级别控制的就是读数据。
3、& 那更新数据呢?为什么没有脏写?难道事务的锁不管吗?
答:不管你用什么隔离级别,同一个事务中,只要有更新或删除数据,这个排它锁就会持续到最后才释放。也就是说,不管如何隔离,哪怕是使用“未提交读”,事务都会保证不脏写。
4、& 不可重复读和幻想读到底有什么区别?看上去貌似是一样的。
答:如表格中所述,不可重复读,只是指,在同一个事务内,已经读取到的数据行在第二次读取时行内的数据发生了变化。而幻像读是指,已经读取到了数据,第二次读时,就多出新行了。这两种级别是不一样的,一种是修改行,一种是新增行,尽管差别小,但仍是两个级别。
接下来讲讲如何在开发中使用事务及隔离级别。
READ UNCOMMITTED
SET TRANSACTIONISOLATIONLEVELREADUNCOMMITTED
Begin tran
*fromsysobject
READ COMMITTED
SET TRANSACTIONISOLATIONLEVELREADCOMMITTED
Begin tran
*fromsysobjects
REPEATABLE READ
SET TRANSACTIONISOLATIONLEVELREPEATABLEREAD
Begin tran
*fromsysobject
SERIALIZABLE
SET TRANSACTIONISOLATIONlevelSERIALIZABLE
Begin tran
*fromsysobjects
其实从上面的示例语句差异来看,都只是Read后的关键字不一样,也就表示事务隔离级别就是针对读数据的。
那用事务就是为了锁住读数据,即隔离数据吗?
当然不是,隔离只是事务的一个特性。我们平时用事务多用的是事务的“原子性”,也就是一个事务可以有多批语句,可以把这些语句当作一个整体来执行,并利用事务的”持久性&,一次性提交或回滚所有的操作。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:77211次
积分:1295
积分:1295
排名:千里之外
原创:32篇
转载:50篇
(1)(1)(1)(1)(2)(1)(1)(2)(3)(3)(4)(1)(2)(1)(12)(3)(2)(1)(1)(39)> 博客详情
事务是访问数据库的一个操作序列,数据库通过事务集来完成对数据库的存取;
事务必须服从:原子性,一致性,隔离性和持久性;
1、原子性:原子性就是不可分割性,事务要么全部被执行,要么全部不被执行;全部的子事务提交成功,则所有对数据库的操作被提交数据库的状态发生改变;数据库只要有一条子事务没有被执行,其他子事务对数据库的操作也会被回滚,数据库回到执行事务之前的状态;
2、一致性:事务的执行是的数据库从一种状态变化为另外一种状态;
3、隔离性:在事务提交之前,不允许把该事务对数据库的操作提供给其他事务;
4、持久性:事务一旦正确提交,就会对数据库进行永久性的修改;
悲观锁:悲观锁主要是通过数据库的锁机制来实现的,它在对数据进行操作时会将数据进行加锁,来实现对数据的独占性。
典型的sql语句是:select * from emp where name='scott' for update;
缺点是:开销太大;
实现方式:session.lock等
乐观锁:乐观锁是在数据库加一列version,读取数据时,把version一块读取,提交时必须保证提交的version大于读取时的version否则提交失败;提高了高并发下的数据执行效率;
缺点:具有一定的局限性,只能在自己的系统中来实现,外部系统的用户不受我们控制,容易出现“脏读”;
实现;Hibernate内嵌了乐观锁,通过optimistic-lock=“version”即可;
人打赏支持
码字总数 3314
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥

我要回帖

更多关于 innodb事务模型和锁 的文章

 

随机推荐