一、什么是事务
事务是数据库区别于文件系统的重要特性之一。事务会把数据库从一种状态变为另一种状态。在数据库提交工作时,可以确保要么所有的修改都已经保存了,要么所有修改都不保存。
InnoDB存储引擎完全符合ACID的特性。ACID分别为
-
原子性(atomicity)
-
一致性(consistency)
-
隔离性(isolation)
-
持久性(durability)
1.1事务的特性
A,原子性
原子性是指整个数据库事务是不可分割的工作单位,只有使事务中所有的数据库操作都执行成功,才算整个事务成功。事务中任何一个语句的执行失败,已经执行的sql语句也必须撤销,数据库回滚事务之前的状态。
C,一致性
一致性指事务将数据库从一种状态转变为下一种的状态。在事务开始之前和事务 结束以后,数据库的完整性约束没有被破坏。
I,隔离性
事务的隔离性要求读写每个事务的对象对其他操作对象能相互分离。这类机制使用锁来实现。
D,持久性
事务一旦提交,其结果就是永久性的。即使发生宕机等故障,数据库也能恢复。
二、事务的隔离级别
在了解mysql的事务隔离级别之前,我们先说一下为什么要有事务的隔离级别?我们知道Mysql的innodb引擎是支持事务的,当多个线程控制多个事务进行读写操作时就会出现一些意想不到的事情,主要有以下情况:
-
脏读 一个事务可以读到其他事务没有提交的修改数据,这种现象被称为“脏读”
-
不可重复读 所谓不可重复读就是一个事务内执行两次查询可能得到不同的查询结果。
-
幻读 所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行。
例如:
insert into student (sname,birthday,ssex,sid,classid) values ();
delelt form student where sid = ?
update student set sname =?,birthday = ?
select * from student where...
alter table student add index(sname)
name varchar(20) primary key auto_increment,
sal decimal(20,2) default 2000,
eid char(20) not null unique
SQL规范的四种隔离级别:
-
READ UNCOMMITTED(未提交读) 此隔离级别可能会出现“脏读”,“不可重复读”,“幻读”等问题。从性能上来说,此级别没有别其他的级别好太多,却缺乏其他级别的很多好处,除非真的有非常必要额理由,否则实际中不要使用这种隔离级别。
-
READ COMMITTED(提交读) 大多数数据库的默认隔离级别都是READ COMMITTED,但是Mysql除外。此隔离级别可以解决脏读的问题,但有时会出现两次执行同样的查询,可能会得到不一样结果的问题,也就是不可重复读的问题。换句话说,此级别解决了脏读的问题,但是可能会出现不可重复读和幻读的问题。
-
REPETABLE READ(可重复读) REPETABLE READ是Mysql的默认隔离级别。因为该隔离级别下,读取的是事务开始时的行数据版本,并且通过采用Next-key Lock算法,避免了“幻像问题”,所以该级别保证了在同一个事务中多次读取同样记录的结果是一致的。换句话说,此隔离级别解决了“脏读”,“不可重复读的问题”,以及“幻读”的问题。
-
SERIALIZABLE(可串行化) SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的“脏读”,“不可重复读”,“幻读”等所有问题。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。实际中很少使用,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑用该级别。