📄 事务和锁.txt
字号:
事务的完整性
1、原子性
事务必须是原子的,在事务结束的时候,事务中的操作要么全部完成,要么什么也没做。
如果事务中的某些操作被写到了磁盘上,而另外一些没有,就违反了原子性。
2、一致性
在事务执行前数据库应当处于一致状态,而当事务结束的时候,数据库又会回到一致性状态。
(银行转帐)
3、隔离性
每个事务都必须与其他事务产生的结果隔离开来。隔离性是两个事务之间的屏障。
验证隔离性的方法即:在相同的初始数据集合上多次重复执行一组的特定的事务集合,而每次得到相同的结果。
例如:1用户更新100行数据,在1用户的事务正在执行的时候,2用户要删除1用户修改的数据,如果删除真的发生了,说明1,2事务之间的隔离性还不够。
相对于单用户来说,隔离性在多个用户数据库中更为重要。
4、持久性
指不管系统是否发生了故障,事务的处理结果都要永久保存。
事务的缺陷
1、脏读
事务最明显的缺陷是在事务提交之前,他对数据所做的修改就为其他事务所见。
如果一个事务读取了另外一个事务尚未提交的更新,就叫做脏读。
Tran1-----------------------
begin transaction
use pubs
update jobs set job_desc = 'accp' where job_id = 1
Tran2-----------------------
begin transaction
set transaction isolation level read uncommitted (必须手动设计,否则会取默认值)
select * from jobs where job_id = 1
所以要结束第一个事务。
2、不可重复读
类似于脏读,只不过它发生在事务能看到其他事务已经提交的数据更新的情况下。
真正的隔离性指一个事务不会影响到另一个事务。
在一个事务内进行同样的读操作,每次都应该得到相同的结果。
如果两次读取的数据不一样,说明出现了不可重复读型事务缺陷。
Tran1-----------------------
begin transaction
use pubs
select * from jobs where job_id = 1
Tran2-----------------------
begin transaction
update jobs set job_desc = 'accp' where job_id = 1
commit transaction
重复Tran1
读出的数据将发生改变
3、幻影读
危害最小的事务完整性缺陷是幻影读。
和不可重复读有些类似,幻影读指的也是一个事务的更新结果影响到另一个事务的情况。
与不可重复读不同的是:用select获取数据的时候,可能会获取其他的数据。
Tran1-----------------------
begin transaction
update jobs set job_desc = 'accp' where job_id = 1
select * from jobs where job_desc = 'accp'
Tran2-----------------------
begin transaction
update jobs set job_desc = 'accp' where job_id = 1
commit transaction
重复事务1
得到两个结果。
事务的隔离级别
1、Read Uncommitted 未提交读
最不严格的隔离级别,它不能防止任何一种事务缺陷,根本就没有在事务之间提供隔离。
等同于nolock,这种设置适合报表或只读的应用程序,这种锁只能防止数据崩溃。
2、Read Committed 提交读
默认的隔离级别,防止陷入过渡锁争用的泥潭。
3、Repeatable Read 可重复读
可以防止脏读和不可重复读。
4、Serializable 可串行读(连续的)
完全没有事务的并发概念。用在银行,帐务系统,股票市场。
锁持续期
隔离级别 共享锁持续期 排它锁持续期
Read Uncommitted 无 持有锁的时间仅能够保证不会出现物理崩溃
Read Committed 在事务读取数据的期间持有锁 持有锁直到事务提交
Repeatable Read 持有锁直道事务提交 持有锁直到事务提交
Serializable 持有锁直道事务提交 持有锁直到事务提交,同时还使用键锁,防止插入
锁的粒度
行锁:一行 (25行可升级为一个页锁)
页锁:一个页面 8K
扩展盘区锁: 8个页面
表锁:整个表
数据库锁:
键锁:
锁模式
共享锁:一个简单的读锁。宣称(“我正在读取数据”)
排它锁:
死锁:
系统会检测完成工作量最少的事务作为牺牲品,但是不太准确。
既然系统帮我们检索并处理死锁,为什么我们还要手动处理死锁呢?
1、两个事务产生死锁时,SQL Server会检测到,但是三个事务出现死锁:
事务1等待事务2,事务2等待事务3,事务3等待事务1。
虽然官方提供的帮助上面说可以检测到,但实际上还是不理想。
2、我们可以手动的控制哪个事务放弃任务。
step1
use pubs
begin tran
update jobs set job_desc = 'vb' where job_id = 1
step 2
use pubs
begin tran
update jobs set job_desc = 'sql' where job_id = 2
update jobs set job_desc = 'asp' where job_id = 1
step3
use pubs
begin tran
update jobs set job_desc = 'c++' where job_id = 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -