事务是用来解决特定场景的问题,在mysql中有些操作需要借助多个sql才能够解决,假设我们有个账户余额表,我们需要进行转账,转账无非就是加减操作,但是在转账过程中必然会出现中间结果,如果在转账未完全成功之前,A账户减300在B账户还未增加300执勤程序出现问题了,这时候该怎么办呢?
事务就是来解决这样的一些问题,所谓事务就是把多个执行的sql打包成一个整体,这个整体在执行过程中能够做到要么整个都执行完,要么一个也不执行就可避免出现上述转账到一半的中间情况。
注意:此处的“一个也不执行”不是这sql真的没执行而是执行到一半出现错误,数据库会自动进行“还原操作”,相当于把前面执行的sql给进行“撤销”,最终看起来像一个也没执行的这样的效果这种机制称之为“回滚(rollback)”。(回滚就类似于退货不想要了原路返回)。
同时也把事务支持上述的“特性”称为“原子性”。
数据库是如何知到并泽阳回滚的呢?如何知到前面的sql做出了咋么样的修改“
数据库内部存在一系列的“日志体系(println)”,记录到文件中(既可以应对程序崩溃也可以应对主机电线(虽然点点但是回滚日历还是存在的因此下次主机商店数据库启动的时候就可以根据原来的回滚日历的内容就行回滚操作了))。
那么问题来了像drop database这样的操作可以回滚回来吗??不能的!!!
回滚操作是针对事务的,而上述操作属于正确的操作没有发生错误,因此不会自动触发回滚。
事务的使用
(1)开启事务:start transaction;
(2)执行多条sql语句
(3)返回rollback(全部失败)或 commit(全部成功)。
事务设计的四个核心特性:
1.原子性(最重要的特性)
2. 一致性(描述的是事务执行前后数据库上的数据都是合法状态不会出现非法的历史结果)
3.持久性(事务执行完毕之后就会修改应硬盘上的数据,事务都是会持久生效的)
4.隔离性(非常不好解释)。
隔离性:描述了多个事务并发执行的视乎,相互之间产生的印象是怎样的。
此时因为这些同事执行的事物,恰好也是很对同一个表进行一些增删查改就可能会引入一些问题
mysql是一个“客户端服务器结构的程序”一个服务器通常会给多个客户端同时提供服务,因此很可能多个客户端同时给这个服务器提交事务来执行与之相对,服务器就需要同时执行这多个事务,此时就是并发执行的。
1)脏读
有两个事务A和B并发执行,其中事务A在针对某个表的数据进行修改,A执行的过程中B也去读取这个表的数据,当B读完之后A又把表中的数据又改成了别的,这就导致了B读到的数据,并不是最终的正确结果,而是读到了临时性的“脏数据(往往是指数据过期了过时了的错误数据)”。
那么该如何解决这个问题呢?我们可以在一个事物A读的时候不允许另一个事物B读(也可以称为给写操作加锁)这样就很好的解决了脏读的问题。
2)不可重复性
有三个事务ABC,首先事务A进行一个修改操作,A执行完毕的时候,提交数据,接下来B执行,事务B读取刚才A提交的数据,在B读取的过程中又来了一个事物C,C又对刚才A修改的数据再次做出了修改,此时对于B来说后续读到的结果就和第一次读到的结果是不一样的,这个过程就叫做“不可重复性”(体现的是事物B,一个事物里多次读取的结果不一样,如果有多个事务每个事务读到的结果不一样这种情况认为是正常的~~)。
解决这个问题的方式也很简单,一个事物在读取数据的过程中其他事务不能修改它正在的数据。(给读者加锁)。
3)幻读问题
有一个事务A在读取数据,读的过程中,另一个事务B增添了/删除了一些其他的数据,此时站在
A的视角,多次读取的数据内同虽然一样但是“结果集”不同
解决方式,约定只有有事务在读代码,就不能进行任何操作这样的操作称为“串行化”(比如多个客户端通识类提交了多个事务过来但是服务器一个一个来执行事务)。
并发执行事务过程中,涉及到的三个问题和隔离性有什么关系呢?
在mysql中提供了四个隔离级别,可以通过配置文件来设置当当前服务器的隔离级别是哪个级别,设置不同的隔离级别,就会使事物之间的并发执行的影响产生不同的差别,从而会影响到上述三个问题的情况。
1)read uncommitted 读未提交
这种情况下一个事物可以读取另一个事物未提交的数据法,此时就可能不会产生脏读不可重复性,幻读三种问题,但是此时多个事务并发执行的程度是最高的,执行速度也是最快的。
2)read committed 读已提交
这种情况下,一个事物只能读取另一个事物提交后的数据(给写操作加锁了)此时可能会产生不可重复性,幻读问题(脏读问题解决了)此时并发程度会降低,执行的速度会变慢事务之间的隔离性(事物之间的相互影响变小了得到的数据更准确了)提高了。
3)repeatable read 可重复读
这种情况下,相当于给写操作和读操作都加锁了此时可能会产生幻读问题(不可重复性和脏读问题解决了)并发程度进一步减低,执行速度进一步减慢事务之间的隔离性进行一步提高了。
4)serializable 串行化
此时所有的事务都在服务器上一个接一个执行的,此时解决了脏读不可冲独行,幻读问题,并发程度最低执行速度最慢,隔离性最高,数据最准确。
我们可以根据需要选择合适的隔离级别。