数据库-锁的基本知识

–锁定一个表的某一行
set transaction isolation level red uncommitted

select * from table rowlock where id=1

–锁定数据库的一个表
select * from table with(holdlock)

–加锁语句

例1:死锁的发生
T1:
begin tran
select * from table (holdlock) (holdlock意思是加共享锁,直到事务结束之后才释放)
update table set column1=‘hello’

T2:
begin tran
select * from table(holdlock)
update table set column1=‘world’

解释:假设T1,T2同时达到select,T1对table加共享锁,T2也对其加共享锁,当T1的select执行完,准备执行update时,根据锁机制,T1的共享锁需要升级到排它锁才能执行接下来的update.在升级排它锁前,必须等table上的其他共享锁释放,但因为holdlock这样的共享锁只有等事务结束后才释放,所以因为T2的共享锁不释放而导致T1等待(等待T2释放共享锁以便于自己升级为排它锁),同理,也因为T1的共享锁不释放而导致T2等待,这样死锁就产生了。

例2:
T1:
begin tran
update table set column1=‘hello’ where id=10

T2:
begin tran
update tbale set column=‘world’ where id=20

很多人认为他有机会产生死锁,但实际要看清楚,如果id是主键上面有索引,那么T1会一下子找到该条记录(id=10的记录)。然后对该条记录加排它锁,T2,同样,一下子通过索引定位到记录,然后对id=20的记录加排它锁,这样T1,T2各更新个的,互不影响。这种情况不会产生死锁。

但是如果id只是普通的一列,没有索引,那么当T1对id=10这一行加排它锁后 ,,T2为了找到id=20,需要进行全表扫描,那么就会预先对表加上共享锁或更新锁或者是排它锁(依赖于数据库执行策略和方式,比如第一次执行和第二次执行数据库执行策略就会不同)。但因为T1已经为一条记录加了排它锁,导致T2的全表扫描进行不下去,就导致T2等待。【这样应该不会产生死锁吧,只要T1执行完成,T2再继续执行就好了,这样似乎耗时比较久】

死锁的解决:
例3:
T1:
begin tran
select * from table(xlock)–xlock意思是直接对表加排它锁
update table set column=‘hello’

T2:
begin tran
select * from table(xlock)
update table set column1=‘world’
解释:当T1的select执行时,直接对表加上排它锁,T2在执行select时,就需要等T1完全执行完成之后才能执行,排斥了死锁的发生。但是如果有很多的用户同时请求,那他们都必须等待。在大并发情况下,让大家都等待的情况似乎不太友好,所以,这里引入更新锁。【虽然说这种情况能够防止死锁的发生,但我总觉得这不是最好的方法】

更新锁(Update lock) 为解决死锁,引入更新锁。

T1:
begin tran
select * from table(updlock) (加更新锁)
update table set column1=‘hello’

T2:
begin tran
select * from table(updlock)
update table set column1=‘world’

更新锁的意思是:“我现在只想读,你们别人也可以读,但我将来可能会做更新操作,我已经获取了从共享锁(只读的)到排它锁(用来更新)的资格。”一个事务只能有一个更新锁获此资格。

分区表:

分区方案例1:下面穿件一个分区函数,然后再创建这个分区函数使用的分区方案,这个分区方案将每个分区映射到不同文件组。代码如下:
create partition function MyPF1(int)
as range left
for values(5000000,1000000,1500000)
go
create partition schema MyPS1
as partition MyPF1
to(fg1,fg2,fg3,fg4)
分区案例2:先创建一个分区函数,然后再创建这个分区函数的分区方案,这个分区方案将多个分区映射到同一个文件组。
create partition function MyPF2(int)
as range left
for values(5000000,1000000,1500000)
go
create partition schema MyPS2
as partition MyPF2
to (fg1, fg1, fg1, fg2)
分区方案3:将所有分区映射到同一个文件组
create partition function MyPF3(int)
as range left
for values(5000000,1000000,1500000)
go
crete partition schema MyPS3
as partition MyPF3
all to (fg1)
分区方案4:该分区方案指定了“next used”文件组。
create partition function MyPF4(int)
as range left
for values(5000000,1000000,1500000)–4个分区
go
create partition shema MyPS4
as partition MyPF4
to (fg1,fg2,fg3,fg4,fg5)–5个文件组

那么文件组fg5将自动被标记为“NEXR USED”文件组

分区方案5:这个方案指定了"[primary]" 文件组
create partition function MyPF5(int)
as range left
for values(‘2008/01/01’,‘2009/01/01’)
go
create partition schema MyPS5
as partition MyPF5
to([primary],fg1,fg2)–此时的主文件组是什么??

**最后必须明白一点,一张表最多只能有1000个分区

分区表:下面看一个完整的例子:

–创建分区函数
create partition function MyPF(datetime)
range right
for values(‘2007-1-1’,‘2008-1-1’)
go
–创建分区方案
create partition schema MyPS
as partition MyPF
to(fg1,fg2,fg3)–三个文件组
go
–创建分区表
create table orders
(
OrderID int identiy(1,1) primary key,
OrderDate datetime,
CustID varchar(10)
)
on MyPS(OrderDate)

create table stu
(
stuid int primary key identity(1,1) ,
stuname varchar(10) not null,
stuschool varchar(20) foreign key references schooltbale(schoolName),–加外键约束
stuage int default((0)),–加默认值约束
stusex nvarchar(2) check(stusex=N’男’ or stusex=N’女’)–加检查约束,格式:check(条件表达式)

左连接:
select*
from employee left outer join department
on employee.departmentID=department.departmentID

内连接:
select *
from employee
inner join department
on employee.departmentID=department.departmentID
等同于下面的语句:
select *
from employee,department
where employee.departmentID=department.departmentID

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值