数据库的六种隔离级别的自我理解:
隔离级别(isolation level)分类:未提交事务(read uncommitted)
已提交事务(read committed)
可重复度(repeatableread)
可序列化(serializable)最高级别
其实这几种隔离级别最终是对数据库增删改查进行的锁的限制。
比如说在中写入
create table Product(ProductID int ,Price money);
insert into Produtc values(1,15); --向表中添加ID为1,价格为15的商品
事务1中
begin transaction tran1
declare @Price money
select @Price=Price
from Production
where ProductID=1
waitfor delay '00:00:30' --延迟30秒
if @Price>10
begin
update Product
set Price=Price-10
where ProductID=1
end
commit
在事务2中写入
begin transaction tran2
update Product
set Price=Price*0.6
where ProdcutID=1
commit
如果先运行事务1 ,在30秒之内运行事务2那么,该表Price字段的值变为-1.
为了控制这一事情的发生可以添加可重复读的隔离级别来控制它(个人理解仿佛是更新Update的事务控制)在select 字段 from 表的时候加上With (UpdLock)
再例如:添加员工表。添加4位员工。现在有100元奖金分配到组号是10的员工里面。
create table MyEmployees(EmployeeID int,GroupID int,Salary money)
create clustered index i1 on dbo.MyEmployees(GroupID)
insert into dbo.MyEmployees values(1,10,1000)
insert into dbo.MyEmployees values(2,10,1000)
insert into dbo.MyEmployees values(3,20,1000)
insert into dbo.MyEmployees values(4,30,1000)
declare @Fund money=100,@Bonus money,@NumberOfEmployees int
begin tran PayBonus
select @NumberOfEmployees=COUNT(*)
from dbo.MyEmployees
where GroupID=10
--筛选出10的组号
waitfor delay '00:00:30'
if @NumberOfEmployees>0
begin
set @Bonus=@Fund/@NumberOfEmployees
update dbo.MyEmployees
set Salary=Salary+@Bonus
where GroupID=10
print '奖金剩余'+cast(@Fund-(@@rowcount*@Bonus) as varchar(6))
end
commit
新建事务2,往表中添加位员工,刚好该员工组号为10
begin tran NewEmployee
insert into dbo.MyEmployees values(8,10,1000)
commit
此时可以用可序列化隔离级别来控制(可序列化仿佛就是插入语句的事务控制)在select 字段 from 表的时候加上With (holdLock)