您的当前位置:首页如何合理使用数据库锁

如何合理使用数据库锁

2023-11-13 来源:哗拓教育

死锁,在我们的项目中有发生过,但不频繁;但是因为锁处理的不好,不能合理地规划锁,导致性能下降是经常发生的。通过本文章,除了了解如何避免死锁外,更多的内容是如何使用锁。本文不会讲的很细,有的地方也不是很严谨,但是不影响对内容的理解。更细节和高级的知识,可以百度。

 

二、什么是锁

我们这里讲的锁,是数据库的锁(lock)。当数据库要对某个表,或者某条数据修改时,会首先将其加锁,防止其他进程或事务修改它,以免产生不可预期的结果。关于锁的定义,锁的类型,大家可以搜索。锁的内容(或者称为对象,比如表,表的记录),一般称之为资源。

锁一般有两个级别:行级锁和表级锁。前者的锁定范围是表记录,后者的范围是整表。显然,后者的范围更大。

 

三、何时会发生“锁”

当执行update语句时,数据库会对修改范围内的表记录加锁;

当你修改表的结构时,比如 alter table…,数据库会对表加锁

当你执行select 1 from bsuser for update 时,会对整表加锁。这种语法俗称“显式加锁”。

锁的有效期会从加锁开始直到事务结束(提交或者回滚)。

我不知道有没有主动释放锁的语法,感兴趣的可以查一查。

 

四、什么是死锁

锁不可怕,在系统运行期间,数据库不停地产生锁,释放锁,是很平常的事情,但是可怕的是死锁(deadlock),发生死锁,会导致多个进程阻塞等待。这时候,数据库会提示“系统在申请资源时,检测到死锁”类似的提示信息。死锁就像十字路口塞车一样,四个方向都走不了。

死锁发生有四个必要条件,我只讲最后一个,也是最关键的,就是两个事务互相申请被对方持有的资源。举例:进程(事务)A持有资源R1,进程(事务)B持有资源R2,现在进程A申请R2,进程B申请R1。就是两个进程互相申请被对方加锁(持有)的资源,且互不相让,死锁发生了。

发生死锁后,数据库会在等待一段时间后,根据一定的原则,牺牲掉一个进程,以避免死锁持续下去。

 

五、锁的危害

数据库锁是保证数据数据正确被修改的必不可少的手段,是关系型数据库很重要的一个保证数据完整性的工具。这里不说锁的优点,单说其缺点,然后研究怎么规避这些缺点,降低锁的负面影响。

1、      降低系统性能。一般资源被进程锁定,其他要申请该资源的进程就要等待,直到资源被前一个进程释放,这个等待过程就是系统性能降低的过程。等待的越久,系统性能下降的约厉害。

2、      导致死锁。死锁会导致更长时间的进程等待,而且这种等待是无解的,只有通过外部力量的干涉才能解锁,比如数据库介入,牺牲掉一个进程。这样这个进程的操作就会被回滚。

锁等待或者死锁对用户的直接影响是,如果用户的一个界面操作导致的数据库操作被锁阻塞,该处理进程处于等待状态,那用户的操作就会被冻结,不会得到响应。用户的话说就是“界面卡了”。这种情况如果多了,卡的时间长了,会导致用户的体验急剧下降,如果出现死锁,还会导致用户所做的修改不能更新到数据库中,被回滚。

 

六、如何降低锁的影响,避免死锁

我们在实践中,要了解锁发生的原因,锁的机制,正确编程,合理使用锁机制。

1、      避免“锁”

有时候,必须通过锁确保程序执行完美。但是凡事都要有代价。有时候我们需要仔细将加锁带来的副作用和带来的好处做个对比。如果带来的坏处远远大于带来的好处,或者换句话说,如果带来的好处非常小,我们就可以不使用锁。我举个例子。在对考核计划增加考核对象时,要检查不能加入重复的考核对象。为了完美实现这个业务逻辑,需要对考核计划加锁,使得在增加对象时,其他程序都不可以增加对象。这样做完美地实现了这个业务逻辑,但是由于是对整表加锁,大大增加了锁冲突的可能,而且,如果不这样做的话,根据用户的使用场景分析,考核对象重复增加的可能性也极低。这种情况下,就可以不使用锁。为了避免锁冲突(这种大的副作用),我可以容忍在某种极端情况下导致考核对象重复的情况发生(极小概率出现的副作用)。但是后面我会给出一个方案,来确保程序完美的前提下,如何缩小锁的粒度(不锁表)。

2、      尽量缩短“锁”的时间

使用锁的一个原则就是 尽可能晚地加锁,尽可能早地释放锁。也就是说,要合理规划处理逻辑,只在必须的最后时刻才执行update语句(加锁),并尽可能早提交或回滚事务(释放锁)。一个错误的例子就是:

   (1)update ………………………

   (2)复杂的耗时的java代码

   (3)commit

如果可能话,就把 (1)和(2)调换下顺序,推迟加锁的时间。

缩短锁的时间,不能完全避免冲突,但是可以降低发生冲突的概率。就行在大街上走,走的快一些,尽量减少在大街上行走的时间,可以降低被熟人看见概率是一个道理。

3、      减小锁的粒度

只对必要的资源加锁,不扩大锁的范围。

select 1 from 表 for update这种锁全表要坚决避免,如果要锁指定的行,加上where限定条件。

和2一样,减小锁的粒度,也能降低发生锁冲突的概率。

4、      避免死锁。

前面说过,死锁发生的根本原因就是不合理的资源申请顺序,如果多个程序都要使用相同的某几个资源,但是申请顺序不一致,就可能导致死锁发生。因此,我们要约定一个确定资源申请顺序的一个标准,大家都来遵循它。

1)按照资源id的大小顺序(比如我要锁定多条员工记录,我按照员工号的排序从大到小锁定)

2)对有层级关系的资源,按照层级从高到低的顺序申请。比如”单据头->单据明细行”的顺序

按照资源名称排序从大到小进行申请。比如按照表的名称排序。

如何合理使用数据库锁

 

一、前言

死锁,在我们的项目中有发生过,但不频繁;但是因为锁处理的不好,不能合理地规划锁,导致性能下降是经常发生的。通过本文章,除了了解如何避免死锁外,更多的内容是如何使用锁。本文不会讲的很细,有的地方也不是很严谨,但是不影响对内容的理解。更细节和高级的知识,可以百度。

 

二、什么是锁

我们这里讲的锁,是数据库的锁(lock)。当数据库要对某个表,或者某条数据修改时,会首先将其加锁,防止其他进程或事务修改它,以免产生不可预期的结果。关于锁的定义,锁的类型,大家可以搜索。锁的内容(或者称为对象,比如表,表的记录),一般称之为资源。

锁一般有两个级别:行级锁和表级锁。前者的锁定范围是表记录,后者的范围是整表。显然,后者的范围更大。

 

三、何时会发生“锁”

当执行update语句时,数据库会对修改范围内的表记录加锁;

当你修改表的结构时,比如 alter table…,数据库会对表加锁

当你执行select 1 from bsuser for update 时,会对整表加锁。这种语法俗称“显式加锁”。

锁的有效期会从加锁开始直到事务结束(提交或者回滚)。

我不知道有没有主动释放锁的语法,感兴趣的可以查一查。

 

四、什么是死锁

锁不可怕,在系统运行期间,数据库不停地产生锁,释放锁,是很平常的事情,但是可怕的是死锁(deadlock),发生死锁,会导致多个进程阻塞等待。这时候,数据库会提示“系统在申请资源时,检测到死锁”类似的提示信息。死锁就像十字路口塞车一样,四个方向都走不了。

死锁发生有四个必要条件,我只讲最后一个,也是最关键的,就是两个事务互相申请被对方持有的资源。举例:进程(事务)A持有资源R1,进程(事务)B持有资源R2,现在进程A申请R2,进程B申请R1。就是两个进程互相申请被对方加锁(持有)的资源,且互不相让,死锁发生了。

发生死锁后,数据库会在等待一段时间后,根据一定的原则,牺牲掉一个进程,以避免死锁持续下去。

 

五、锁的危害

数据库锁是保证数据数据正确被修改的必不可少的手段,是关系型数据库很重要的一个保证数据完整性的工具。这里不说锁的优点,单说其缺点,然后研究怎么规避这些缺点,降低锁的负面影响。

1、      降低系统性能。一般资源被进程锁定,其他要申请该资源的进程就要等待,直到资源被前一个进程释放,这个等待过程就是系统性能降低的过程。等待的越久,系统性能下降的约厉害。

2、      导致死锁。死锁会导致更长时间的进程等待,而且这种等待是无解的,只有通过外部力量的干涉才能解锁,比如数据库介入,牺牲掉一个进程。这样这个进程的操作就会被回滚。

锁等待或者死锁对用户的直接影响是,如果用户的一个界面操作导致的数据库操作被锁阻塞,该处理进程处于等待状态,那用户的操作就会被冻结,不会得到响应。用户的话说就是“界面卡了”。这种情况如果多了,卡的时间长了,会导致用户的体验急剧下降,如果出现死锁,还会导致用户所做的修改不能更新到数据库中,被回滚。

 

六、如何降低锁的影响,避免死锁

我们在实践中,要了解锁发生的原因,锁的机制,正确编程,合理使用锁机制。

1、      避免“锁”

有时候,必须通过锁确保程序执行完美。但是凡事都要有代价。有时候我们需要仔细将加锁带来的副作用和带来的好处做个对比。如果带来的坏处远远大于带来的好处,或者换句话说,如果带来的好处非常小,我们就可以不使用锁。我举个例子。在对考核计划增加考核对象时,要检查不能加入重复的考核对象。为了完美实现这个业务逻辑,需要对考核计划加锁,使得在增加对象时,其他程序都不可以增加对象。这样做完美地实现了这个业务逻辑,但是由于是对整表加锁,大大增加了锁冲突的可能,而且,如果不这样做的话,根据用户的使用场景分析,考核对象重复增加的可能性也极低。这种情况下,就可以不使用锁。为了避免锁冲突(这种大的副作用),我可以容忍在某种极端情况下导致考核对象重复的情况发生(极小概率出现的副作用)。但是后面我会给出一个方案,来确保程序完美的前提下,如何缩小锁的粒度(不锁表)。

2、      尽量缩短“锁”的时间

使用锁的一个原则就是 尽可能晚地加锁,尽可能早地释放锁。也就是说,要合理规划处理逻辑,只在必须的最后时刻才执行update语句(加锁),并尽可能早提交或回滚事务(释放锁)。一个错误的例子就是:

   (1)update ………………………

   (2)复杂的耗时的java代码

   (3)commit

如果可能话,就把 (1)和(2)调换下顺序,推迟加锁的时间。

缩短锁的时间,不能完全避免冲突,但是可以降低发生冲突的概率。就行在大街上走,走的快一些,尽量减少在大街上行走的时间,可以降低被熟人看见概率是一个道理。

3、      减小锁的粒度

只对必要的资源加锁,不扩大锁的范围。

select 1 from 表 for update这种锁全表要坚决避免,如果要锁指定的行,加上where限定条件。

和2一样,减小锁的粒度,也能降低发生锁冲突的概率。

4、      避免死锁。

前面说过,死锁发生的根本原因就是不合理的资源申请顺序,如果多个程序都要使用相同的某几个资源,但是申请顺序不一致,就可能导致死锁发生。因此,我们要约定一个确定资源申请顺序的一个标准,大家都来遵循它。

1)按照资源id的大小顺序(比如我要锁定多条员工记录,我按照员工号的排序从大到小锁定)

2)对有层级关系的资源,按照层级从高到低的顺序申请。比如”单据头->单据明细行”的顺序

按照资源名称排序从大到小进行申请。比如按照表的名称排序。

如何合理使用数据库锁

标签:操作   项目   计划   font   indent   修改   信息   mit   nbsp   

小编还为您整理了以下内容,可能对您也有帮助:

如何合理使用数据库锁死锁,在我们的项目中有发生过,但不频繁;但是因为锁处理的不好,不能合理地规划锁,导致性能下降是经常发生的。通过本文章,除了了解如何避免死锁外,更多的内容是如何使用锁。本文不会讲的很细,有的地方也不是很严谨,但是不影响对内容的理解。更细节和高级的知识,可以百度。

二、什么是锁

我们这里讲的锁,是数据库的锁(lock)。当数据库要对某个表,或者某条数据修改时,会首先将其加锁,防止其他进程或事务修改它,以免产生不可预期的结果。关于锁的定义,锁的类型,大家可以搜索。锁的内容(或者称为对象,比如表,表的记录),一般称之为资源。

锁一般有两个级别:行级锁和表级锁。前者的锁定范围是表记录,后者的范围是整表。显然,后者的范围更大。

三、何时会发生“锁”

当执行update语句时,数据库会对修改范围内的表记录加锁;

当你修改表的结构时,比如 alter table…,数据库会对表加锁

当你执行select 1 from bsuser for update 时,会对整表加锁。这种语法俗称“显式加锁”。

锁的有效期会从加锁开始直到事务结束(提交或者回滚)。

我不知道有没有主动释放锁的语法,感兴趣的可以查一查。

四、什么是死锁

锁不可怕,在系统运行期间,数据库不停地产生锁,释放锁,是很平常的事情,但是可怕的是死锁(dead

lock),发生死锁,会导致多个进程阻塞等待。这时候,数据库会提示“系统在申请资源时,检测到死锁”类似的提示信息。死锁就像十字路口塞车一样,四个方向都走不了。

死锁发生有四个必要条件,我只讲最后一个,也是最关键的,就是两个事务互相申请被对方持有的资源。举例:进程(事务)A持有资源R1,进程(事务)B持有资源R2,现在进程A申请R2,进程B申请R1。就是两个进程互相申请被对方加锁(持有)的资源,且互不相让,死锁发生了。

发生死锁后,数据库会在等待一段时间后,根据一定的原则,牺牲掉一个进程,以避免死锁持续下去。

五、锁的危害

数据库锁是保证数据数据正确被修改的必不可少的手段,是关系型数据库很重要的一个保证数据完整性的工具。这里不说锁的优点,单说其缺点,然后研究怎么规避这些缺点,降低锁的负面影响。

1、 降低系统性能。一般资源被进程锁定,其他要申请该资源的进程就要等待,直到资源被前一个进程释放,这个等待过程就是系统性能降低的过程。等待的越久,系统性能下降的约厉害。

2、 导致死锁。死锁会导致更长时间的进程等待,而且这种等待是无解的,只有通过外部力量的干涉才能解锁,比如数据库介入,牺牲掉一个进程。这样这个进程的操作就会被回滚。

锁等待或者死锁对用户的直接影响是,如果用户的一个界面操作导致的数据库操作被锁阻塞,该处理进程处于等待状态,那用户的操作就会被冻结,不会得到响应。用户的话说就是“界面卡了”。这种情况如果多了,卡的时间长了,会导致用户的体验急剧下降,如果出现死锁,还会导致用户所做的修改不能更新到数据库中,被回滚。

六、如何降低锁的影响,避免死锁

我们在实践中,要了解锁发生的原因,锁的机制,正确编程,合理使用锁机制。

1、 避免“锁”

有时候,必须通过锁确保程序执行完美。但是凡事都要有代价。有时候我们需要仔细将加锁带来的副作用和带来的好处做个对比。如果带来的坏处远远大于带来的好处,或者换句话说,如果带来的好处非常小,我们就可以不使用锁。我举个例子。在对考核计划增加考核对象时,要检查不能加入重复的考核对象。为了完美实现这个业务逻辑,需要对考核计划加锁,使得在增加对象时,其他程序都不可以增加对象。这样做完美地实现了这个业务逻辑,但是由于是对整表加锁,大大增加了锁冲突的可能,而且,如果不这样做的话,根据用户的使用场景分析,考核对象重复增加的可能性也极低。这种情况下,就可以不使用锁。为了避免锁冲突(这种大的副作用),我可以容忍在某种极端情况下导致考核对象重复的情况发生(极小概率出现的副作用)。但是后面我会给出一个方案,来确保程序完美的前提下,如何缩小锁的粒度(不锁表)。

2、 尽量缩短“锁”的时间

使用锁的一个原则就是 尽可能晚地加锁,尽可能早地释放锁。也就是说,要合理规划处理逻辑,只在必须的最后时刻才执行update语句(加锁),并尽可能早提交或回滚事务(释放锁)。一个错误的例子就是:

(1)update ………………………

(2)复杂的耗时的java代码

(3)commit

如果可能话,就把 (1)和(2)调换下顺序,推迟加锁的时间。

缩短锁的时间,不能完全避免冲突,但是可以降低发生冲突的概率。就行在大街上走,走的快一些,尽量减少在大街上行走的时间,可以降低被熟人看见概率是一个道理。

3、 减小锁的粒度

只对必要的资源加锁,不扩大锁的范围。

select 1 from 表 for update这种锁全表要坚决避免,如果要锁指定的行,加上where限定条件。

和2一样,减小锁的粒度,也能降低发生锁冲突的概率。

4、 避免死锁。

前面说过,死锁发生的根本原因就是不合理的资源申请顺序,如果多个程序都要使用相同的某几个资源,但是申请顺序不一致,就可能导致死锁发生。因此,我们要约定一个确定资源申请顺序的一个标准,大家都来遵循它。

1)按照资源id的大小顺序(比如我要锁定多条员工记录,我按照员工号的排序从大到小锁定)

2)对有层级关系的资源,按照层级从高到低的顺序申请。比如”单据头->单据明细行”的顺序

按照资源名称排序从大到小进行申请。比如按照表的名称排序。

如何合理使用数据库锁

一、前言

死锁,在我们的项目中有发生过,但不频繁;但是因为锁处理的不好,不能合理地规划锁,导致性能下降是经常发生的。通过本文章,除了了解如何避免死锁外,更多的内容是如何使用锁。本文不会讲的很细,有的地方也不是很严谨,但是不影响对内容的理解。更细节和高级的知识,可以百度。

二、什么是锁

我们这里讲的锁,是数据库的锁(lock)。当数据库要对某个表,或者某条数据修改时,会首先将其加锁,防止其他进程或事务修改它,以免产生不可预期的结果。关于锁的定义,锁的类型,大家可以搜索。锁的内容(或者称为对象,比如表,表的记录),一般称之为资源。

锁一般有两个级别:行级锁和表级锁。前者的锁定范围是表记录,后者的范围是整表。显然,后者的范围更大。

三、何时会发生“锁”

当执行update语句时,数据库会对修改范围内的表记录加锁;

当你修改表的结构时,比如 alter table…,数据库会对表加锁

当你执行select 1 from bsuser for update 时,会对整表加锁。这种语法俗称“显式加锁”。

锁的有效期会从加锁开始直到事务结束(提交或者回滚)。

我不知道有没有主动释放锁的语法,感兴趣的可以查一查。

四、什么是死锁

锁不可怕,在系统运行期间,数据库不停地产生锁,释放锁,是很平常的事情,但是可怕的是死锁(dead

lock),发生死锁,会导致多个进程阻塞等待。这时候,数据库会提示“系统在申请资源时,检测到死锁”类似的提示信息。死锁就像十字路口塞车一样,四个方向都走不了。

死锁发生有四个必要条件,我只讲最后一个,也是最关键的,就是两个事务互相申请被对方持有的资源。举例:进程(事务)A持有资源R1,进程(事务)B持有资源R2,现在进程A申请R2,进程B申请R1。就是两个进程互相申请被对方加锁(持有)的资源,且互不相让,死锁发生了。

发生死锁后,数据库会在等待一段时间后,根据一定的原则,牺牲掉一个进程,以避免死锁持续下去。

五、锁的危害

数据库锁是保证数据数据正确被修改的必不可少的手段,是关系型数据库很重要的一个保证数据完整性的工具。这里不说锁的优点,单说其缺点,然后研究怎么规避这些缺点,降低锁的负面影响。

1、 降低系统性能。一般资源被进程锁定,其他要申请该资源的进程就要等待,直到资源被前一个进程释放,这个等待过程就是系统性能降低的过程。等待的越久,系统性能下降的约厉害。

2、 导致死锁。死锁会导致更长时间的进程等待,而且这种等待是无解的,只有通过外部力量的干涉才能解锁,比如数据库介入,牺牲掉一个进程。这样这个进程的操作就会被回滚。

锁等待或者死锁对用户的直接影响是,如果用户的一个界面操作导致的数据库操作被锁阻塞,该处理进程处于等待状态,那用户的操作就会被冻结,不会得到响应。用户的话说就是“界面卡了”。这种情况如果多了,卡的时间长了,会导致用户的体验急剧下降,如果出现死锁,还会导致用户所做的修改不能更新到数据库中,被回滚。

六、如何降低锁的影响,避免死锁

我们在实践中,要了解锁发生的原因,锁的机制,正确编程,合理使用锁机制。

1、 避免“锁”

有时候,必须通过锁确保程序执行完美。但是凡事都要有代价。有时候我们需要仔细将加锁带来的副作用和带来的好处做个对比。如果带来的坏处远远大于带来的好处,或者换句话说,如果带来的好处非常小,我们就可以不使用锁。我举个例子。在对考核计划增加考核对象时,要检查不能加入重复的考核对象。为了完美实现这个业务逻辑,需要对考核计划加锁,使得在增加对象时,其他程序都不可以增加对象。这样做完美地实现了这个业务逻辑,但是由于是对整表加锁,大大增加了锁冲突的可能,而且,如果不这样做的话,根据用户的使用场景分析,考核对象重复增加的可能性也极低。这种情况下,就可以不使用锁。为了避免锁冲突(这种大的副作用),我可以容忍在某种极端情况下导致考核对象重复的情况发生(极小概率出现的副作用)。但是后面我会给出一个方案,来确保程序完美的前提下,如何缩小锁的粒度(不锁表)。

2、 尽量缩短“锁”的时间

使用锁的一个原则就是 尽可能晚地加锁,尽可能早地释放锁。也就是说,要合理规划处理逻辑,只在必须的最后时刻才执行update语句(加锁),并尽可能早提交或回滚事务(释放锁)。一个错误的例子就是:

(1)update ………………………

(2)复杂的耗时的java代码

(3)commit

如果可能话,就把 (1)和(2)调换下顺序,推迟加锁的时间。

缩短锁的时间,不能完全避免冲突,但是可以降低发生冲突的概率。就行在大街上走,走的快一些,尽量减少在大街上行走的时间,可以降低被熟人看见概率是一个道理。

3、 减小锁的粒度

只对必要的资源加锁,不扩大锁的范围。

select 1 from 表 for update这种锁全表要坚决避免,如果要锁指定的行,加上where限定条件。

和2一样,减小锁的粒度,也能降低发生锁冲突的概率。

4、 避免死锁。

前面说过,死锁发生的根本原因就是不合理的资源申请顺序,如果多个程序都要使用相同的某几个资源,但是申请顺序不一致,就可能导致死锁发生。因此,我们要约定一个确定资源申请顺序的一个标准,大家都来遵循它。

1)按照资源id的大小顺序(比如我要锁定多条员工记录,我按照员工号的排序从大到小锁定)

2)对有层级关系的资源,按照层级从高到低的顺序申请。比如”单据头->单据明细行”的顺序

按照资源名称排序从大到小进行申请。比如按照表的名称排序。

如何合理使用数据库锁

标签:操作项目计划fontindent修改信息mitnbsp

如何掌握SQLServer的锁机制

数据库的锁 锁是数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性。 我们知道,多个用户能够同时操纵同一个数据库中的数据,会发生数据不一致现象。即如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同

数据库的锁

锁是数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性。 我们知道,多个用户能够同时操纵同一个数据库中的数据,会发生数据不一致现象。即如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。这些问题包括:丢失更新、脏读、不可重复读和幻觉读:

1.当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,,这将导致数据丢失。例如,两个编辑人员制作了同一文档的电子复本。每个编辑人员地更改其复本,然后保存更改后的复本,这样就覆盖了原始文档。最后保存其更改复本的编辑人员覆盖了第一个编辑人员所做的更改。如果在第一个编辑人员完成之后第二个编辑人员才能进行更改,则可以避免该问题。

2. 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。例如,一个编辑人员正在更改电子文档。在更改过程中,另一个编辑人员复制了该文档(该复本包含到目前为止所做的全部更改)并将其分发给预期的用户。此后,第一个编辑人员认为目前所做的更改是错误的,于是删除了所做的编辑并保存了文档。分发给用户的文档包含不再存在的编辑内容,并且这些编辑内容应认为从未存在过。如果在第一个编辑人员确定最终更改前任何人都不能读取更改的文档,则可以避免该问题。

3.不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

4.幻觉读是指当事务不是执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主复本时,发现作者已将未编辑的新材料添加到该文档中。如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免该问题。

所以,处理多用户并发访问的方法是加锁。锁是防止其他事务访问指定的资源控制、实现并发控制的一种主要手段。当一个用户锁住数据库中的某个对象时,其他用户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。为了控制锁定的资源,应该首先了解系统的空间管理。在SQL Server 2000系统中,最小的空间管理单位是页,一个页有8K。所有的数据、日志、索引都存放在页上。另外,使用页有一个,这就是表中的一行数据必须在同一个页上,不能跨页。页上面的空间管理单位是盘区,一个盘区是8个连续的页。表和索引的最小占用单位是盘区。数据库是由一个或者多个表或者索引组成,即是由多个盘区组成。放在一个表上的锁对整个表的并发访问;放在盘区上的锁了对整个盘区的访问;放在数据页上的锁了对整个数据页的访问;放在行上的锁只对该行的并发访问。

SQL Server 2000的锁机制

SQL Server 2000 具有多粒度锁定,允许一个事务锁定不同类型的的资源。为了使锁定的成本减至最少,SQL Server 自动将资源锁定在适合任务的级别。锁定在较小的粒度(例如行)可以增加并发但需要较大的开销,因为如果锁定了许多行,则需要控制更多的锁。锁定在较大的粒度(例如表)就并发而言是相当昂贵的,因为锁定整个表了其它事务对表中任意部分进行访问,但要求的开销较低,因为需要维护的锁较少。SQL Server 可以锁定行、页、扩展盘区、表、库等资源。

行是可以锁定的最小空间, 行级锁占用的数据资源最少,所以在事务的处理过程中,允许其他事务继续操纵同一个表或者同一个页的其他数据,大大降低了其他事务等待处理的时间,提高了系统的并发性。

页级锁是指在事务的操纵过程中,无论事务处理数据的多少,每一次都锁定一页,在这个页上的数据不能被其他事务操纵。在SQL Server 7.0以前,使用的是页级锁。页级锁锁定的资源比行级锁锁定的数据资源多。在页级锁中,即使是一个事务只操纵页上的一行数据,那么该页上的其他数据行也不能被其他事务使用。因此,当使用页级锁时,会出现数据的浪费现象,也就是说,在同一个页上会出现数据被占用却没有使用的现象。在这种现象中,数据的浪费最多不超过一个页上的数据行。

表级锁也是一个非常重要的锁。表级锁是指事务在操纵某一个表的数据时,锁定了这个数据所在的整个表,其他事务不能访问该表中的其他数据。当事务处理的数据量比较大时,一般使用表级锁。表级锁的特点是使用比较少的系统资源,但是却占用比较多的数据资源。与行级锁和页级锁相比,表级锁占用的系统资源例如内存比较少,但是占用的数据资源却是最大。在表级锁时,有可能出现数据的大量浪费现象,因为表级锁锁定整个表,那么其他的事务都不能操纵表中的其他数据。

盘区锁是一种特殊类型的锁,只能用在一些特殊的情况下。簇级锁就是指事务占用一个盘区,这个盘区不能同时被其他事务占用。例如在创建数据库和创建表时,系统分配物理空间时使用这种类型的锁。系统是按照盘区分配空间的。当系统分配空间时,使用盘区锁,防止其他事务同时使用同一个盘区。当系统完成分配空间之后,就不再使用这种类型的盘区锁。特别是,当涉及到对数据操作的事务时,不使用盘区锁。

数据库级锁是指锁定整个数据库,防止任何用户或者事务对锁定的数据库进行访问。数据库级锁是一种非常特殊的锁,它只是用于数据库的恢复操作过程中。这种等级的锁是一种最高等级的锁,因为它控制整个数据库的操作。只要对数据库进行恢复操作,那么就需要设置数据库为单用户模式,这样系统就能防止其他用户对该数据库进行各种操作。

怎么理解数据库的锁?一般锁分别哪几种(数据库锁的类型和作用)

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

在数据库中有两种基本的锁类型:排它锁(ExclusiveLocks,即X锁)和共享锁(ShareLocks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

扩展资料:

排它锁和共享锁的不同之处:

1、共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

排他锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

2、共享锁下其它用户可以并发读取,查询数据。但不能修改,增加,删除数据,资源共享。

3、共享锁又称为读锁(Sharelock,简记为S锁),若事务T对数据对象A加上S锁,则其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。

MySQL从入门到精通(九) MySQL锁,各种锁

锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,除传统的计算资源(CPU、RAM、I/O)争用外,数据也是一种供许多用户共享的资源,如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言是尤其重要,也更加复杂。MySQL中的锁,按照锁的粒度分为:1、全局锁,就锁定数据库中的所有表。2、表级锁,每次操作锁住整张表。3、行级锁,每次操作锁住对应的行数据。

全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将阻塞。其典型的使用场景就是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。但是对数据库加全局锁是有弊端的,如在主库上备份,那么在备份期间都不能执行更新,业务会受影响,第二如果是在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志,会导致主从延迟。

解决办法是在innodb引擎中,备份时加上--single-transaction参数来完成不加锁的一致性数据备份。

添加全局锁: flush tables with read lock; 解锁 unlock tables。

表级锁,每次操作会锁住整张表.锁定粒度大,发送锁冲突的概率最高,并发读最低,应用在myisam、innodb、BOB等存储引擎中。表级锁分为: 表锁、元数据锁(meta data lock, MDL)和意向锁。

表锁又分为: 表共享读锁 read lock、表独占写锁write lock

语法: 1、加锁 lock tables 表名 ... read/write

2、释放锁 unlock tables 或者关闭客户端连接

注意: 读锁不会阻塞其它客户端的读,但是会阻塞其它客户端的写,写锁既会阻塞其它客户端的读,又会阻塞其它客户端的写。大家可以拿一张表来测试看看。

元数据锁,在加锁过程中是系统自动控制的,无需显示使用,在访问一张表的时候会自动加上,MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作。为了避免DML和DDL冲突,保证读写的正确性。

在MySQL5.5中引入了MDL,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作时,加MDL写锁(排他).

查看元数据锁:

select object_type,object_schema,object_name,lock_type,lock_ration from performance_schema_metadata_locks;

意向锁,为了避免DML在执行时,加的行锁与表锁的冲突,在innodb中引入了意向锁,使得表锁不用检查每行数据是否加锁,使用意向锁来减少表锁的检查。意向锁分为,意向共享锁is由语句select ... lock in share mode添加。意向排他锁ix,由insert,update,delete,select。。。for update 添加。

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_lock;

行级锁,每次操作锁住对应的行数据,锁定粒度最小,发生锁冲突的概率最高,并发读最高,应用在innodb存储引擎中。

innodb的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁,对于行级锁,主要分为以下三类:

1、行锁或者叫record lock记录锁,锁定单个行记录的锁,防止其他事物对次行进行update和delete操作,在RC,RR隔离级别下都支持。

2、间隙锁Gap lock,锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事物在这个间隙进行insert操作,产生幻读,在RR隔离级别下都支持。

3、临键锁Next-key-lock,行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap,在RR隔离级别下支持。

innodb实现了以下两种类型的行锁

1、共享锁 S: 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

2、排他锁 X: 允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

insert 语句 排他锁 自动添加的

update语句 排他锁 自动添加

delete 语句 排他锁 自动添加

select 正常查询语句 不加锁 。。。

select 。。。lock in share mode 共享锁 需要手动在select 之后加lock in share mode

select 。。。for update 排他锁 需要手动在select之后添加for update

默认情况下,innodb在repeatable read事务隔离级别运行,innodb使用next-key锁进行搜索和索引扫描,以防止幻读。

间隙锁唯一目的是防止其它事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事务在同一间隙上采用的间隙锁。

显示全文