事务就是一系列的操作,要么都成功,要么都失败。
1、事务的ACID属性
原子性:Atomicity,事务是一个原子操作单位,要么都成功,要么都失败;
一致性:Consistent,事务开始和结束时,数据都必须保持一致的状态,即操作完成后所有的内部数据结构(包括B树索引和双向链表等)都必须是正确的;
隔离性:Isolation,事务在不受外部并发操作影响的独立环境中执行,即事务执行的中间状态对外部是不可见的,反之亦然。
持久性:Durable,事务完成后,它对于数据的修改是永久性的,即使出现系统故障也能保持。
2、并发事务带来的问题:
更新丢失:Lost Update,多个事务同时操作一行数据,由于事务之间互相不知道彼此的存在,就会导致最后的更新覆盖了由其他事务所做的更新。
如果一个用户完成并提交事务之前,另一个用户不能访问同一个文件,则可以避免此问题。
脏读:Dirty Reads,又称无效数据的读出,如果一个事务正在对一条记录做修改,在这个事务完成之前,这条记录的数据就处于不一致状态;此时,另一个事务来读取这条记录,如果不做控制,第二个事务读取了这条数据,并在脏数据的基础上做了处理。这时候如果第一个事务发生回滚,则第二个事务读取的数据无效,不符合一致性要求。
不可重复读:Non-Repeated Reads,在一个事务范围内,两个相同的查询却返回了不同数据,不符合隔离性。
幻读:Phantom Reads,幻读是指当事务不是独立执行时发生的一种现象,例如事务A对一个表中的一些行的数据进行了修改;同时,事务B在这个表中的相同结果集中插入或删除了一些数据。那么,事务A的用户会发现结果集中还存在没有修改的数据行,就好象发生了幻觉一样。幻读违反了事务的隔离性。
一般解决幻读的方法是增加范围锁,锁定检索范围为只读。
对比:脏读是读到了修改数据,幻读是读到了新增或删除数据。
3、事务的隔离级别:
3.1 隔离级别:
未提交读:允许别的事务,去读取这个事务提交之前的数据;
已提交读:不允许别的事务,去读取这个事务提交之前的数据。但是如果事务中有两次读取操作,执行完第一次读取后,另一个数据执行了增删改等操作,那么第一个事务再次读取的时候就会出现不可重复读或者幻读的问题;
可重复读:默认级别。该事务执行期间,不允许其他事务对该事务处理的数据进行操作(通过对数据加锁来实现),保证该事物中多次对数据的查询结果一致。但是如果另一个事务插入新的数据,这种情况是无法阻止的,仍然会产生幻读。
可序列化:就是上面的可重复读是将使用数据范围的锁起来不让别人用,而这里是将涉及数据的表全都锁起来,不允许别人操作。缺点是效率低。
3.2 注意事项:
一次只能设置一个隔离级别选项,而且设置的选项将对该会话连接始终有效,直到显式更改该选项为止。事务中执行的所有读取操作都会在指定的隔离级别的规则下运行,除非语句的FROM子句中的表提示为表指定了其他锁定行为或版本控制行为。
3.3 特征总结:
隔离级别 | 英文名称 | 读数据一致性 | 脏读 | 不可重复读 | 幻读 |
未提交读 | Read uncommitted | 最低级别,只能保证不读取物理上损坏的数据 | 是 | 是 | 是 |
已提交读 | Read committed | 语句级 | 否 | 是 | 是 |
可重复读 | Repeatable read | 事务级 | 否 | 否 | 是 |
可序列化 | Serializable | 最高级别,事务级 | 否 | 否 | 否 |
4、命令
查看当前数据库的事务隔离级别:show variable like ‘tx_isolation’;