数据库事物

1.事物定义

所谓事务,它是一个操做序列,这些操做要么都执行,要么都不执行,它是一个不可分割的工做单位。mysql

2.ACID

ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)所应该具备的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。sql

原子性

原子性是指事务是一个不可再分割的工做单位,事务中的操做要么都发生,要么都不发生。数据库

一致性

一致性是指在事务开始以前和事务结束之后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。安全

隔离性

多个事务并发访问时,事务之间是隔离的,一个事务不该该影响其它事务运行效果。并发

这指的是在并发环境中,当不一样的事务同时操纵相同的数据时,每一个事务都有各自的完整数据空间。由并发事务所作的修改必须与任何其余并发事务所作的修改隔离。工具

并行处理时可能出现问题:性能

脏读:事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,若是事务A提交失败,事务B读到的就是脏数据。

不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。好比,事务B在事务A提交前读到的结果,和提交后读到的结果可能不一样。

幻读:在一个事务内读取到了别的事务插入的数据,致使先后读取不一致。

mysql定义了四种事物的隔离级别:spa

Read Uncommitted:最低的隔离级别,什么都不须要作,一个事务能够读到另外一个事务未提交的结果。全部的并发事务问题都会发生。

Read Committed:只有在事务提交后,其更新结果才会被其余事务看见。能够解决脏读问题。

Repeated Read:在一个事务中,对于同一份数据的读取结果老是相同的,不管是否有其余事务对这份数据进行操做,以及这个事务是否提交。能够解决脏读、不可重复读。

Serialization:事务串行化执行,隔离级别最高,牺牲了系统的并发性。能够解决并发事务的全部问题。
  1. Serializable(串行化):可避免脏读、不可重复读、幻读状况的发生。
  2. Repeatable read(可重复读):可避免脏读、不可重复读状况的发生。
  3. Read committed(读已提交):可避免脏读状况发生。
  4. Read uncommitted(读未提交):最低级别,以上状况均没法保证。

持久性

持久性,意味着在事务完成之后,该事务所对数据库所做的更改便持久的保存在数据库之中,并不会被回滚。线程

即便出现了任何事故好比断电等,事务一旦提交,则持久化保存在数据库中。code

mysql数据库事物

mysql数据库默认的事务隔离级别是:Repeatable read(可重复读)。

mysql数据库引擎

对于MySQL来讲,最具备表明性的表存储引擎就是InnoDB和MyISAM。二者之间最主要的区别就是是否进行外键的数据完整性检查。对于InnoDB存储引擎能够经过外键来进行数据完整性检查,对于MyISAM存储引擎须要开发人员在程序级进行数据关联保证数据完整性。

MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。与其余存储引擎比较,MyISAM具备检查和修复表格的大多数工具。 MyISAM表格能够被压缩,并且它们支持全文搜索。它们不是事务安全的,并且也不支持外键。若是事物回滚将形成不彻底回滚,不具备原子性。若是执行大量的SELECT,MyISAM是更好的选择。

InnoDB:这种类型是事务安全的。它与BDB类型具备相同的特性,它们还支持外键。InnoDB表格速度很快。具备比BDB还丰富的特性,所以若是须要一个事务安全的存储引擎,建议使用它。若是你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表,对于支持事物的InnoDB类型的表,影响速度的主要缘由是AUTOCOMMIT默认设置是打开的,并且程序没有显式调用BEGIN开始事务,致使每插入一条都自动Commit,严重影响了速度。能够在执行SQL前调用BEGIN,多条SQL造成一个事物(即便AUTOCOMMIT打开也能够),将大大提升性能。

并发状况下加锁

InnoDB实现了如下两种类型的行锁

  • 共享锁:容许一个事务去读一行,容许其余事物得到改行的共享锁,可是阻止其余事务得到改行数据的排他锁。
  • 排他锁:容许获取排他锁的事务更新数据,阻止其余事务取得相同的数据集共享读锁和排他写锁。

事务能够经过如下语句显示给记录集加共享锁或排锁

共享锁:SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。

排他锁:SELECT * FROM table_name WHERE ... FOR UPDATE。

注意:用SELECT .. IN SHARE MODE得到共享锁,主要用在须要数据依存关系时确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操做。可是若是当前事务也须要对该记录进行更新操做,则颇有可能形成死锁,对于锁定行记录后须要进行更新操做的应用,应该使用SELECT ... FOR UPDATE方式获取排他锁。

InnoDB行锁是经过索引上的索引项来实现的,这一点MySQL与Oracle不一样,后者是经过在数据中对相应数据行加锁来实现的。InnoDB这种行锁实现特色意味者:只有经过索引条件检索数据,InnoDB才会使用行级锁,不然,InnoDB将使用表锁!

MyISAM提供锁模式主要有表共享锁(Table Read Lock)和表独占写锁(Table Write Lock)

  • 对MyISAM的读操做,不会阻塞其余用户对同一表读请求,但会阻塞对同一表的写请求;
  • 对MyISAM的写操做,则会阻塞其余用户对同一表的读和写操做;
  • MyISAM表的读操做和写操做之间,以及写操做之间是串行的。

当一个线程得到对一个表的写锁后,只有持有锁线程能够对表进行更新操做。其余线程的读、写操做都会等待,直到锁被释放为止。

MyISAM在执行查询语句(SELECT)前,会自动给涉及的全部表加读锁,在执行更新操做(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁,这个过程并不须要用户干预,所以用户通常不须要直接用LOCK TABLE命令给MyISAM表显式加锁。

并发锁

在必定条件下,MyISAM也支持查询和插入的并发进行,MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别能够为0、1或2。

  • 当concurrent_insert设置为0时,不容许并发插入。
  • 当concurrent_insert设置为1时,若是MyISAM容许在一个读表的同时,另外一个进程从表尾插入记录。这也是MySQL的默认设置。
  • 当concurrent_insert设置为2时,不管MyISAM表中有没有空洞,都容许在表尾插入记录,都容许在表尾并发插入记录。
相关文章
相关标签/搜索