数据库的事务和锁

Posted vince66

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库的事务和锁相关的知识,希望对你有一定的参考价值。

事务

  是作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性.

1、A (Atomicity) 原子性

事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

2、C (Consistency)一致性

事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修
改,以保持所有数据的完整性。事务结束时,所有的
内部数据结构(如 B树索引或双向链表)都必须是正确的。

3、I (Isolation) 隔离性

并发事务所做的修改必须与任何其他并发事务所做的
修改隔离。事务识别数据时数据所处的状态,要么是
另一并发事务修改它之前的状态,要么是第二个事务
修改它之后的状态,事务不会识别中间状态的数据。

4、D (Durability) 持久性

事务完成之后,它对于系统的影响是永久性的。该修
改即使出现系统故障也将一直保持。

锁定是 Microsoft SQL Server数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制。

在事务获取数据块当前状态的依赖关系(比如通过读取或修改数据)之前,它必须保护自己不受其他事务对同一数据进行修改的影响。事务通过请求锁定数据块来达到此目的。锁有多种模式,如共享或独占

1、脏读

某个事务读取的数据是另一个事务正在处理的数据。而另一个事务可能会回滚,造成第一个事务读取的数据是错误的。

2、不可重复读

在一个事务里两次读入数据,但另一个事务已经更改了第一个事务涉及到的数据,造成第一个事务读入旧数据。

3、幻读

幻读是指当事务不是独立执行时发生的一种现象。例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

4、更新丢失

多个事务同时读取某一数据,一个事务成功处理好了数据,被另一个事务写回原值,造成第一个事务更新丢失。

事务隔离级别:

读未提交 读已提交 可重复读 可串行化


锁模式:

1、共享锁

共享锁(S 锁)允许并发事务在封闭式并发控制下读取 (SELECT)资源。有关详细信息,请参阅并发控制的类型。资源上存在共享锁(S锁)时,任何其他事务都不能修改数据。读取操作一完成,就立即释放资源上的共享锁(S锁),除非将事务隔离级别设置为可重复读或更高级别,或者在事务持续时间内用锁定提示保留共享锁(S锁)。

2、更新锁(U锁)

更新锁在共享锁和排他锁的杂交。更新锁意味着在做一个更新时,一个共享锁在扫描完成符合条件的数据后可能会转化成排他锁。

这里面有两个步骤:

1) 扫描获取Where条件时。这部分是一个更新查询,此时是一个更新锁。

2) 如果将执行写入更新。此时该锁升级到排他锁。否则,该锁转变成共享锁。

更新锁可以防止常见的死锁。

3、排他锁

排他锁(X 锁)可以防止并发事务对资源进行访问。排他锁不与其他任何锁兼容。使用排他锁(X锁)时,任何其他事务都无法修改数据;仅在使用 NOLOCK提示或未提交读隔离级别时才会进行读取操作。


如何避免死锁

(1).按同一顺序访问对象。(注:避免出现循环) (2).避免事务中的用户交互。(注:减少持有资源的时间,较少锁竞争) (3).保持事务简短并处于一个批处理中。(注:同(2),减少持有资源的时间) (4).使用较低的隔离级别。(注:使用较低的隔离级别(例如已提交读)比使用较高的隔离级别(例如可序列化)持有共享锁的时间更短,减少锁竞争) (5).使用基于行版本控制的隔离级别:2005中支持快照事务隔离和指定READ_COMMITTED隔离级别的事务使用行版本控制,可以将读与写操作之间发生的死锁几率降至最低:

以上是关于数据库的事务和锁的主要内容,如果未能解决你的问题,请参考以下文章

MySQL专题2: 事务和锁

MySQL数据库高级——事务和锁

面试中的老大难-mysql事务和锁,一次性讲清楚!

事务和锁

15 Django事务和锁应用

Oracle事务和锁