前言
事务出现就是为了保证数据的准确性。
事务介绍
事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
案例:
A 借给 B 100元钱 ; 操作分为两步, A-100元, B+100元, 不能出现A-100 元,而B没有加100元的情况。事务就是为了解决这类问题。
隔离级别
MySQL的四种隔离级别
READ UNCOMITTED (未提交读)
在READ UNCOMITED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为能读(Dity Re这个级别会保致很多问题,从性能上来说,READ UICTT不会比其他的级别好太多,但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中-般很少使用。
READ COMMITTED (提交读)
大多数数据库系统的默认隔离级别都是READ COMMITTED (但MySQL不是)。READ COMMITTED满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见” 已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫做不可重复读(nonrepeatableread),因为两次执行同样的查询,可能会得到不一样的结果。
REPEATABLE READ (可重复读)
REPEATABLE READ 解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读(Phantom Read的问题。所谓幻读,指的是当某个事务在该取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row). InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC Mutiversion Concurrency Control)解决了幻读的问题,重点:这里更新范围数据的时候的,如果在另外一个事务中插入了在这个范围内的记录,那么这次更新再提交的时候还是会出现未更新到的问题,故MySQL在这种情况下,还给我们加入了GAP锁(间隙锁)和next-lock锁,需要建立索引哦,保证其他事务不能在你更新的范围内插入数据。
可重复读是MySQL的默认事务隔离级别。
SERIALIZABLE (可串行化)
SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读问题。简单来说,SERIALIZABLE会在读取的每一行数据都加锁,所以它可以造成大量的超时和锁争用的问题。实际应用中很少使用该隔离级别,只有在非常需要保持一致性,但是可以接受没有并发的情况下,才考虑采用该级别。
小结:MySQL的事务默认级别为可重复读,可以通过以下参数进行修改MySQL的隔离级别
set transaction_isolation='read-uncommitted'; -- 设置会话级别的隔离级别,全局和永久有效设置与其他参数设置一致,值分别为read-uncommitted,
read-committed,repeatable-read,serializable。
事务
begin delete from xxx; update xxx set xxx; commit/rollback; -- 提交/回滚事务
查询事务提交方式:
mysql> show global variables like 'autocommit'; -- ON 表示自动提交, OFF表示关闭自动提交
set global autocommit=0; -- 关闭自动提交,设置全局级别。
读写锁
select ...... lock in share mode; --读锁,其他会话无法修改其锁定行的数据。 select ...... for update; --写锁,其他会话无法修改其锁定行的数据。
保存点 SAVEPOINT
begin delete from xxx; savepoint xxx update xxx set xxx; rollback to xxx; -- 回滚事务update的操作,delete 保留
隐式提交
导致提交的非事务语句: DDL语句: (ALTER、CREATE 和 DROP) DCL语句: (GRANT、REVOKE 和 SET PASSWORD) 锁定语句:(LOCK TABLES 和 UNLOCK TABLES) 导致隐式提交的语句示例: TRUNCATE TABLE LOAD DATA INFILE SELECT FOR UPDATE
总结
事务是MySQL保证数据的重要组成部分,上述事务在异常情况下也需要保证,这个时候我们就需要了解MySQL的日志,redo log 和 undo log.