事务的特性
-
原子性:所有操作一起提交,不会只执行一部分。即事务是原子性的,不可以分割。
-
一致性:事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
-
隔离性:同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
-
持久性:事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
事务的隔离等级
-
读未提交:其它事务可以查询到事务A更改数据但还未提交的数据。
-
读已提交:只能读取到已提交的数据。
-
可重复读:事务A在开始时就创建一个视图,在事务中使用的数据均从这份视图中查询。
-
串行化: 读数据加读锁,写数据加写锁,前面的锁释放后面的事务才可以进行;完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
- mysql的默认隔离等级是 可重复读
事务的问题
- 脏读:事务B读到了事务A修改的数据,后来事务A回滚,导致事务B用了错误的数据
- 不可重复读:事务A频繁的读取某个表的数据,事务B更改了这个表的数据,导致事务A读到的数据和之前的不一样了
- 幻读: 事务A将某字段的值全部都改了,事务B又将数据改为之前的数据了,导致事务A结束刷新后发现数据没有变化,就像出现了幻觉
解决方案
隔离等级 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 未解决 | 未解决 | 未解决 |
读已提交 | 解决 | 未解决 | 未解决 |
可重复读 | 解决 | 解决 | 未解决 |
串行化 | 解决 | 解决 | 解决 |
其它
-
数据库默认隔离级别: mysql ---repeatable,oracle,sql server ---read commited
-
mysql binlog的格式三种:statement,row,mixed
-
为什么mysql用的是repeatable而不是read committed:在 5.0之前只有statement一种格式,而主从复制存在了大量的不一致,故选用repeatable
-
为什么默认的隔离级别都会选用read commited 原因有二:repeatable存在间隙锁会使死锁的概率增大,在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行
-
在RC级用别下,主从复制用什么binlog格式:row格式,是基于行的复制!
-
为什么在互联网项目中选择读已提交,而不用可重复读
- 可重复读隔离级存在间隙锁,导致出现死锁的几率比读已提交大的多!读已提交隔离级别下,不存在间隙锁,其他事务是可以插入数据!
- 在可重复读隔离级别下,条件列未命中索引会锁表!而在读已提交隔离级别下,只锁行
- 在可重复读隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性!
网友评论