1.1 什么是事务
-
简而言之,事务是一组原子性的SQL查询,或者说一个独立的工作的单元。(联想操作系统的PV原语,它就是原子性的,)什么是原子性呢? 原子是组成物理世界的基本微粒,原来认为 原子是不可被分割的。所以说 事务的原子性 就是执行这个事务 它不能被中断的。这一组SQL查询语句是一组命令( select update, delete等命令),这命令是不可被分割和中断的。事务内的几条语句的执行,要么都成功,要么都失败,不会存在部分语句成功执行,而其他的失败的情况,这样是违背了原子性的定义的。
-
使用事务
- 使用START TRANSACTION开启事务,COMMIT提交事务,ROLLBACK回滚事务.
- 所谓回滚就是撤销所有对原数据的修改.提交事务是保持对原数据的修改.
-
例子:
START TRANSACTION;#开启事务
SELECT balance FROM checking WHERE ID=1;
UPDATE checking SET banlace =banlace+1 WHERE id=2;
COMMIT;#提交事务
1.2 事务的特征 ACID
原子性
- 原子性开篇用我自己的语言表述过了,以下是课本的上描述:一个事务必须被视为一个不可分割的最小单元,整个事务要么是全部成功,要么的全部失败回滚.
一致性
- 一致性是指: 数据库总是从一个一致性状态 转换为另一个一致性状态,若事务执行失败或者没有提交 这个一致性状态就不会改变转换.
隔离性
- 一般来说(不同隔离级别,对事务可见性是有区别),一个事务所做的修改 在最终提交前对其他事务是不可见的.比如 我对某一行的数据做的修改, 并且此时我没有提交我的修改,那么其他事务是不知道我已经做了修改了.这一点 可以联想java 的关键字 valatile 保证可见这种特性,就像数据库的数据放在主内存里面,我们的事务可以看出一个线程,我们只是拿到主内存数据的拷贝,在自己的工作内存中对这个拷贝进行修改,修改之后必须要更新主内存的值,才会被其他线程知晓.这就是可见性.
持久性
- 一旦事务提交了,则该事务所作的修改将会被持久化在数据库里面.即使系统发生了崩溃,数据也不会发生丢失.
事务弊端
- 事务最直观的一个弊端就是: 因为我们要保证ACID特性,那么我们就需要更多的CPU处理能力和更大的内存和更多的磁盘空间来保证这些特性.简单来说事务的实现 消耗CPU ,内存, 磁盘.
- 是否使用事务取决我们业务的具体场景.对于 主要是查询业务的操作,就可以不使用事务.
事务的隔离级别
- 较低级别的隔离可以实现更高程度的并发操作.
未提交读:READ UNCOMMITED
- 事务的修改,即使没有被提交,对其他事务也是可见的.
- 脏读:其他事务可以读取到没有被提交的数据. 一般不使用这种隔离级别,会产生很大问题.
提交读: READ COMMITED
- 大多数的数据库的隔离级别使用的是提交读(mysql不是).
- 一个事务从开始到提交前,所做的任何修改 对其他 的事务是不可见的. 也叫做不可重复读.因为两次同样的查询,最后的得到的两次结果是不一样的.(因为第二次查询时,有其他的事务若提交的修改,得到的数据肯定就和第一次不一样了).
可重复读:REPEATABLE READ —mysql的默认隔离级别
- 可重复读解决了脏读的问题. 保证了一个同一个事务中的多次读取同样纪律的结果是一样的.
- 可重复读不发解决幻读的问题: 当某个事务再次读取到 该范围的记录时,另一个事务又在该范围内插入了新的数据,当之前的事务再次读取时,会产生幻行,
- 幻读的解决: InnoDB 和XtraDB 使用多版本并发控制(MVVC),解决幻读的问题. InnoDB 使用间隙锁策略防止幻读的出现,间隙锁使得InnoDB 不仅仅锁定查询涉及的行, 还对索引中的间隙进行锁定,以防止幻影行的插入.
可串行化 :SERIALIZABLE
- 最高的隔离级别,强制事务串行执行.在读取的每一行都加上了锁,会导致锁争用 的问题