上文我们提到了数据库异常重启以及数据备份的数据一致性问题。其中提到mysql的解决方案就是两阶段提交。
如果昨天我们讲的是数据的物理一致性,那么今天我们要探讨的问题是数据的逻辑一致性。
事务,什么是事务?事务是一组操作,这一组操作看起来像是一个操作一样,全部成功或者全部失败。举例说明:银行转账业务:a账户减少->b账户增加。
mysql的事务是在引擎层实现的。myisan不支持事务。
事务的四个特点,ACID。
事务和线程:
问题:脏读,不可重复读,幻读,。
sql的事务隔离级别:读未提交,读提交,可重复读,串行化
读未提交:顾名思义还未提交的事务,被其他事务读了。–大家都是透明的。
读提交:一个事务只有提交后,别的事务才能读取到。
可重复读:一个事务看到的数据,总是和这个事务启动时看到的数据是一致的。同时,未提交的事务对其他事务是不可见的。–我开始的能看到什么,那结束前我就还是看到那些。
串行化:对于同一行记录,写会加写锁,读会加读锁。当读写冲突时,后访问的事务必须等前一个事务完成后,才能继续执行。
提交类型 | V1 | V2 | V3 |
---|---|---|---|
读未提交 | 2 | 2 | 2 |
读提交 | 1 | 2 | 2 |
可重复读 | 1 | 1 | 2 |
串行化 | 1 | 1 | 2 |
从这里可以看到,同一条记录在系统里可能会存在多个值的情况,这是inodb支持事务的基础。它是怎么做到的呢?
其中串行化,因为事务B将1修改为2时,会被锁住。因此要等事务A提交之后,事务B才会执行。
在数据访问时,数据库会创建一个试图作为逻辑结果的输出。在可重复读的隔离级别下,视图是在事务启动的时候创建的,而在读提交级别下,视图是在每个sql语句执行的时候创建的。读未提交没有视图的概念,串行化以加锁的方式防止并行访问。
show variables like “transaction_isolation” #查询当前实例的隔离级别
mysql的事务隔离是怎么实现的呢?
mysql的每条记录在更新的时候,都会记录一条回滚操作。通过回滚操作可以得到前一个状态的值。
讲一个值从1按照顺序改为2,3,4,则在回滚日志里会记录一下信息,这就为同一个值记录了不同版本的信息。不同时刻启动的事务会有不同的read-view。
set autocommit=1 启动线程的自动提交事务