myisam引擎不支持事务
概念
一个事情由n个单元组成,这n个单元在执行过程中,要么同时成功,要么同时失败,这就把n个单元放在了一个事务中。
例子:一张试卷由多道题目组成,当答题完毕,你需要交整张试卷,而不是将每道题分次提交。试卷就可以理解为一个事务。
事务的特性:ACID
A:atomicity(原子性),原子性是指事务是一个不可分割的工作单位,事务中的操作,要么都发生,要么都不发生
例:你购物车加了两件衣服,你把两件作为一个订单提交支付,要么一起成功,要么都失败,不存在上衣付完钱了,裤子还没付完的情况,反之亦然。
C:consistency(一致性),在一个事务中,事务前后数据的完整性必须保持一致。
例:假设用户A和用户B两者的钱加起来一共是200,那么不管A和B之间如何转账,转几次帐,事务结束后两个用户的钱相加起来应该还得是200,这就是事务得一致性。
I:Isolation(隔离性),存在于多个事务中,事务得隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
例:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
D:Durability(持久性),持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
例:我们在操作数据库时,事务提交或者回滚都会直接改变数据库中的值。
事务的操作
在使用事务之前,首先我们要开始事务,我们可以通道start或者begin命令开启事务;如果我们想提交事务可以手动执行commit命令,如果我们想回滚事务,可以执行rollback命令。
注意:在mysql中事务的提交是默认开启的,可以执行show variables like 'autocommit'命令看看,如果是on则证明自动提交已经开启,如果为OFF则需要手动提交。
隔离性引发的并发问题
1)脏读:B事务读取到了A事务尚未提交的数据;
2)不可重复读:B事务读到了A事务已经提交的数据,即B事务在A事务提交之前和提交之后读取到的数据内容不一致(AB事务操作的是同一条数据);
3)幻读/虚读:B事务读到了A事务已经提交的数据,即A事务执行插入操作,B事务在A事务前后读到的数据数量不一致。
事务的隔离级别
为解决隔离性引发的并发问题,数据库提供了事务的隔离机制。
read uncommitted(读未提交):一个事务还没提交时,它做的变更就能被别的事务看到,读取尚未提交的数据,哪个问题都不能解决;
read committed(读已提交):一个事务提交之后,它做的变更才会被其他事务看到,读取已经提交的数据,可以解决脏数据--oracle默认的
repeatable read(可重复读):一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的,可以解决脏读和不可重复读--mysql默认的
serializable(串行化):顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。
-------------------当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。可以解决脏读、不可重复读和幻读---相当于锁表
------------------虽然serializable级别可以解决所有的数据库并发问题,但是它会在读取的每一行数据上都加锁,这就可能导致大量的超时和锁竞争问题,从而导致性能下降。所以我们在实际应用中也很少使用serializable,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。