数据库的ACID和事物的隔离级别
原子性
原子性指一个事物的执行是完整的,不可分割的,一个事物可以同时包含多条sql语句,这些SQL语句要不都成功,要不都失败,是以一个整体。但是并不保证这些SQL是连续执行的。
持久性
指数据会保存到硬盘上,做持久化保存。
一致性
原子性、持久性、隔离性都是为了保证数据的一致性,一致性是指数据在事物执行前后是保持一致的。
隔离性
隔离性针对的是事物与事物之间的属性。指事物与事物之间是互相隔离的,不可见的;
隔离性催生出的四种隔离级别
read uncommitted(读未提交)
事物A可以读到事物B还没有commit的数据;
select 没有加共享锁
insert delete update 加了互斥锁
read committed(读已提交)
事物A读不到事物B没有commit的数据;
事物A读取数据时,通过MVCC(多版本控制)来获取已经提交事物的最新的数据
- List item 会出现幻读可能
事物A在执行事物时,有一条读操作,读取某行数据后,如果事物B更改这条数据,如果事物A再次来读取这条数据时,数据变成事物B更改后的数据,出现了不可重复读
REPEATABLE READ(可重复度)
1.事物A在读取某条数据后,如果事物B重新提交了这条事物的更改,事物A再次读取这条数据还是事物B未提交事物之前的数据,这就保证了事物A的可重复读
2.事物A在在执行事物时,只在第一次读操作的时候生成一个版本,事物B更新这条数据后,后续的读还是会读第一次读取生成的版本的数据,解决了不可重复读
3.如果事物A读取某条数据为空,这时事物B新增这条数据,事物A再次读取这条数据,会有事物B新增的数据,这就是幻读
不重复读是指事物A本来有数据,事物B然后更改数据,事物A再次读取这条数据是事物B更改后的数据------本来有数据,只是更改
幻读是指—本来没数据或多出数据,再次读取有数据,是幻读
日志
undo log
回滚日志,保证数据的原子性,记录的是数据的操作,
更新和删除一条数据在undo会增加很多版本,作为标记,
insert回滚,直接删除这条日志
update回滚,根据roll字段回滚到对应的版本
delete回滚,根据roll字段回滚到对应的版本
undo log日志记录了trx_id和roll_id和delete_bit字段,trx_id字段记录的是这条记录的版本,roll_id字段记录的是回滚的版本,delete_bit字段标记的是否删除
事物A在做select时会查询出对应的trx_id,也就是版本,这个事物后续的查询也只能查询出等于或校这个trx_id字段的版本,所以做到了读写分离
redo log
主要是保证数据的持久性,保证数据不丢失
事物开始时就往redo log日志记录,这时候主要是写入log buff,写完后把数据写入到磁盘
准确的写入顺序是:mysql的log buff —>操作系统的os buff----> redo log ;
默认情况下是mysql的事物日志全部先写入到log buff,然后系统每1s中把log buff的日志写入到磁盘的redo log中,如果出现异常,会丢失1s的数据,1s内mysql可以写入5W条数据,
redo log 是顺序的往磁盘写入,所以效率较高