1.事务的ACID
1. 原子性
一个事务中的操作必须全部成功或者全部失败,不会出现中间状态,即事务不可分割
2. 一致性
本质上是应用层对数据结果的预期结果,即数据结果与预期一致,不会出现不一致的情况
3. 隔离性
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)
4. 持久性
事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
2. 事务的隔离性
SQL 标准的事务隔离级别包括:
2.1 读未提交(read uncommitted)
读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
2.2 读提交(read committed)
读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
2.3 可重复读(repeatable read)
可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
2.4 串行化(serializable )
串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。
3. 事务隔离的实现方式
详见多版本并发控制MVCC篇
4. 长事务问题
在mysql中,需要尽量使用短事务,避免事务过长,原因有三
- 事务过长,则需要保存许多undolog,影响多版本并发效率(MVCC)
- 事务过长,则会影响锁持有时间边长,不利于并发效率,可能拖垮整个库
查看长事务进程(超过60s)
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60
如何避免长事务?
- 在开发过程中,尽可能的减小事务范围,少用长事务
- 如果无法避免,保证逻辑日志空间足够用(增加undo表空间),并且支持动态日志空间增长。
- 监控Innodb_trx表,发现长事务报警。(监控information_schema.innodb_trx或者使用pt工具监控长事务)