Mysql锁及事务的隔离水平

来源:互联网 发布:国家药监局数据查询 编辑:程序博客网 时间:2024/06/06 23:08

锁以及事务处理分离水平(隔离级别)

了解悲观锁和乐观锁的概念

悲观锁:假设会发生并发冲突,回避一切可能违反数据完整性的操作。

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性,注意乐观锁并不能解决脏读的问题(关于脏读稍后解析)。

在一般情况下,悲观锁依靠数据库的锁机制实现,以保证操作最大程度的排他性和独占性,因而会导致数据库性能的大量开销和并发性很低,特别是对长事务而言,这种开销往往过于巨大而无法承受。为了解决这样的问题,乐观锁机制便出现了。乐观锁,大多情况下是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则给予更新,否则认为是过期数据。ok~,关于悲观锁和乐观锁的简单概念就先了解到这。

mysql中的共享锁与排他锁(属于悲观锁,行锁定)

在mysql中,为了保证数据一致性和防止数据处理冲突,引入了加锁和解锁的技术,这样可以使数据库中特定的数据在使用时不让其他用户(进程或事务)操作而为该数据加锁,直到该数据被处理完成后再进行解锁。根据使用目的不同把锁分为共享锁定(也称为读取锁定)排他锁定(写入锁定)

共享锁定:将对象数据变为只读形式的锁定,这样就允许多方同时读取一个数据,此时数据将无法修改。
排他锁定:在对数据进行insert/update/delete时进行锁定,在此时其他用户(进程或事务)一律不能读取数据,从而也保证数据完整性。

以上两种锁都属于悲观锁的应用,还有一点,根据锁定粒度的不同,可分为行锁定(共享锁和排他锁使用应用的就是行锁定),表锁定数据库锁定,可见粒度的不同将影响用户(进程或事务)对数据操作的并发性,目前mysql支持行锁定和表锁定。

事务处理分离水平

事实上,锁的出现更多的是为了在多个用户(进程或事务)同时执行更新操作时保证数据的完整性和一致性,但随之而来的问题是当数据的锁定时间越长,数据同时运行性也会随之降低。也就意味着当一个用户(进程或事务)对数据保存锁定时,其他用户(进程或事务)只能等待锁定解锁,这样也就导致并发访问该数据的同时性较低。所以在多用户(进程或事务)对数据进行更新或者访问的同时如何保证数据的完整性和一致性,这样的情况下需要有一个相对折中的妥协,因为并不是频繁锁定数据或者极致提供同时运行性就是合理的,为了描述这个问题数据库中引入分离水平(有些地方称为隔离级别)的概念来确定事务处理之间的相互影响程度。其规则描述:分离水平越高,数据的完整性也就越高,但同时运行性下降,相反如果分离水平越低数据完整性越低,同时运行性也就提高了。在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务,并发虽然是常见的,但可能会导致不同分离水平下发生不同的数据读取情况,4种分离水平以及可能导致的情景如下:

分离水平 读未提交(脏读) 不可重复读 幻读 READ UNCOMMITTED 会 会 会 READ COMMITTED 不 会 会 REPEATABLE READ 不 不 会 SERIALIZABLE 不 不 不

四种分离水平(隔离级别)

read_uncommitted:这是事务最低的分离水平(隔离级别),它充许别外一个事务可以看到这个事务未提交的数据,会出现脏读、不可重复读、幻读 (分离水平最低,并发性能高)

read_committed:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。可以避免脏读,但会出现不可重复读、幻读问题(锁定正在读取的行,多数数据库默认隔离级别,不是mysql)

repeatable_read:可以防止脏读、不可重复读,但会出幻读(锁定所读取的所有行)

serializable:这是花费最高代价但是最可靠的事务分离水平(隔离级别),事务被处理为顺序执行。保证所有的情况不会发生(锁表,并发性及其低)

原创粉丝点击