並發訪問:
當多個線程訪問同一個資源,會產生並發性問題
並發控制與處理:
樂觀並發控制:一種方式是“后來的更新者獲勝” 這意味着先來的用戶提交的值會在沒有察覺的情況下丟失。
為記錄加鎖以阻止其他事物訪問某些記錄,是避免產生並發沖突的一種技術
悲觀並發控制:
1.一個線程操作表,造成整個表被鎖定
2.其他線程訪問與操作任何記錄都被阻止
3.其他線程可以添加記錄
4.最小的吞吐量、最差的性能
事物恢復與檢查點:
事物指南:
1.事物盡量簡單
2.事物盡量只包含必要的語句;驗證與查詢等語句放置在事物之外
3.避免事物與用戶的交互
避免鎖的問題:
1.丟失的更新
2.臟讀
3.不一致性分析
4.幻象集
鎖的粒度:
鎖的類型:
平衡樂觀與悲觀並發訪問:
1.建立合適的索引
2.操作語句盡量放到短事物中
3.操作語句盡量指定特定的篩選條件、窄的訪問列
4.索引查詢提示
5.應用程序訪問模式
創建表:
create table Employee(id int identity(1,1),name varchar(500),age int) insert Employee values('caochao',34) insert Employee values('ligang',28) insert Employee values('zhangqing',36) insert Employee values('huang',23) go begin tran update Employee set age=age+1 where age>=30
新建一個查詢窗口:
select *from Employee
訪問就被阻塞掉了。沒有結果。
執行刪改查的方法都沒什么用。
select * from Employee where age>30 select * from name,age from employee where age<30 update employee set age=age+1 where age<30 delete employee where age=20
添加是可以的:
insert Employee values('xili',50)
查看鎖的命令:
sp_lock
進行回滾把鎖釋放:
rollback tran
沒有排他鎖:
創建非聚簇索引:
create nonclustered index nc_Employee_age on Employee(age) include(name)
模擬開啟事物不結束:
begin tran update Employee set age=age+1 where age>=30
鎖的情況:
訪問如下兩個語句不行:
select *from Employee select * from Employee where age>30
這條語句可以訪問(鎖住的行不能訪問,不鎖的是可以訪問的):
select name,age from employee where age<30
在非聚集的索引頁面進行了age進行了物理排序,訪問的是在被鎖住行排序的上面。並不需要穿透鎖住的行
這句語句是不能執行的:(無法穿透>30的記錄)
select * from Employee where age<20
在執行跟新語句:
update employee set age=age+1 where age<30
無法執行,查看執行計划,直接進行了表掃描:
在執行一條查詢語句:執行的表掃描 不能進行查詢
select * from Employee where age<30
執行刪除語句:(可以) 執行的是非聚集索引
delete employee where age=20
應用索引提示的方法:
select * from employee with(index=nc_Employee_age) where age<30
查看執行計划:
update 不能用索引提示:
硬性訪問: readpast 繞過被排他鎖鎖住的行,直接往下面進行訪問
select * from Employee with(readpast)
結果:(只能訪問不被鎖住的)