事务锁模拟
讨论角度
主要从锁的种类,锁的范围,上锁和开锁的时机,每种锁与其他锁的兼容性等角度分析问题。
事务隔离级别
事务隔离级别一共分四类:未提交读,提交读,可重复读,序列化读,快照。主要总结模拟后四种。
1 提交读
已提交读是SQL SERVER 默认的事务隔离级别。当事务正在读取数据时,SQL SERVER 会放置共享锁以防止其他事务修改数据,当数据读取完成之后,会自动释放共享锁,其他事务可以进行数据修改。因为共享锁会同时封锁语句执行,所以在事务完成数据修改之前,是无法读取该事务正在修改的数据行。
几点解释:
1)共享锁的概念
又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
2)为什么说放置共享锁后可以防止其他事务修改数据?
共享锁与排它锁是不兼容的,所以打上共享锁后,其他进程就不能修改数据了。
3)提交读隔离级别注意开共享锁的时机
数据读取完成之后,立即释放共享锁。开锁后,其他事务可以放上排他锁,也就是可以修改数据了,一旦有进程拿到排它锁,则其他进程不能读或写这张表,排它锁直到事务结束才释放。
模拟
思路
新建测试数据库和一张测试表,插入两条数据,然后开启事务,在事务中修改新插入的第二条数据,然后打开另一个SQL Server服务器,用另一个账户登入连接测试。
use master
GO
CREATE database TranIsoTest
--提交读隔离级别模拟
--1.创建测试表
create table tb(ID INT,name nvarchar(20))
--2新增记录
INSERT tb (ID,name)VALUES(1,'zg')
INSERT tb (ID,name)VALUES(2,'hxl')
--3开启事务,并进行修改
begin tran
update tb set name='Jack_upd' where ID=2
---4查询事务数量
SELECT @@TRANCOUNT
--不提交事务,打开另一个sqlserver服务器,用另一个账户登入
另一个连接内的脚本
--5打开另一条连接,设置事务隔离级别为(已提交读)
--set Transaction isolation level read committed
--6查询数据,由于当前事务没有提交,所以无法查询数据
select * from tb where ID=2
此时这个连接(进程