事务就是一组原子性的SQL查询,或者说一个独立的工作单元。

事务内的语句,要么全部执行成功,要么全部执行失败。

银行应用是解释事务必要性的一个经典例子。假设一个银行的数据库有两张表:支票表checking和储蓄表savings。现在要从某用户的支票账户转200美元到她的储蓄账户,那么需要三个步骤:

1.检查支票账户余额高于200美元;

2.从支票账户余额减去200美元;

3.在储蓄账户余额增加200美元。

上述三个操作必须在一个事务中,任何一个步骤失败,则必须回滚所有的步骤。

可以用START TRANSACTION开始一个事务,然后要么使用COMMIT提交事务,要么使用ROLLBACK撤销所有的修改。

mysql regexp_replace 数据库版本_死锁

 

事务具有四个特性ACID:原子性、一致性、隔离性、持久性

原子性:一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。

一致性:数据库总是从一个一致性的状态转换到另外一个一致性的状态。在上述例子中,一致性确保了,即使在执行第三、四条语句之间系统崩溃,支票账户也不会损失200美元,因为事务没有提交。

隔离性:通常来说(与隔离级别有关),一个事务所做的修改在最终提交之前,对其他事务是不可见的。

持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中。

 

隔离级别

1.READ UNCOMMITTED(未提交读)

事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读。这个级别会导致很多问题,除非真的有必要,在实际应用中一般很少使用。

2.READ COMMITTED(提交读)

大多数数据库系统的默认隔离级别都是此级别(MySQL不是)。一个事务从开始到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读,因为两次执行同样的查询,可能会得到不一样的结果(在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样)。

3.REPEATABLE READ(可重复读)

解决了脏读的问题,保证了在同一个事务中多次读取同样记录的结果是一致的。但无法解决幻读的问题。

幻读指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

可重复读是MySQL默认事务隔离级别。

4.SERIALIZABLE(可串行化)

最高隔离级别,通过强制事务串行执行,避免了幻读的问题。简单来说,它会在读取的每一行数据上加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别。

 

mysql regexp_replace 数据库版本_数据_02

 

死锁

死锁指的是两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从到导致恶性循环的现象。

当多个事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。

mysql regexp_replace 数据库版本_数据_03

两个事务都执行了第一条update语句,更新了一行数据,同时也锁定了该行数据,接着每个事务都尝试去执行第二条update语句,却发现该行已经被对方锁定,然后两个事务都等待对方释放锁,同时又持有对方需要的锁,则陷入死循环。

为解决这种问题,数据库系统实现了各种死锁检测和死锁超时机制。

InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务进行回滚。

 

MySQL默认采用自动提交模式。也就是说,如果不是显式地开始一个事务,则每个查询都被当作一个事务执行提交操作。

 

 

----《高性能MySQL》