事务
事务的基本概念
最核心特性:原子性,能解决的问题就是批量执行SQL的问题
事务就是专门解决一类特点的场景的问题
事务的由来
例如 张三 账户余额 1000元 李四 账户余额 500元 ,张三给李四转账500元,通过两个SQL语句
update 表名 set 账户余额 = 500 where name = ' 张三',
update 表名 set 账户余额 = 1000 where name = ' 李四',但是这个更新的过程中程序崩溃或者主机断电,第二个SQL语句没有执行成功,那么此时李四的余额还是500,张三的500块就转丢了,为了防止出现这种情况,我们在MySQL中可以使用事务来解决这个问题,
回滚机制(rollback)
所谓事务就是把多个要执行的SQL语句打包成一个整体,确保在运行程序过程中,要么都能执行完,要么都不执行.
此处说的都不执行不是真的不执行,而是当数据库发生错误的时候,会把执行过的SQL语句进行撤销,
同时也把事务支持的上述特性称为原子性,只是针对事务来说,开启事务之后就会记录回滚日志,事务执行过程中出现问题自动触发回滚.
数据库是如何知道,具体是怎样回滚?
在数据内部存在一系列的日志体系,记录到文件中(既可以应对程序崩溃,也可应对主机掉电),当开启事务后,此时每一步执行的sql,都对数据进行了那些修改,这些信息都会记录在案,后续需要回滚,就可以参考之前记录的内容进行还原了.
开启事务之后,一个事务内虽然有多个SQL但也不能有太多.
开启事务 start transaction
写多个SQL
提交事务 commit
在实际开发中都是通过代码的方式来开启事务,批量执行的
事务的基本特性
1.原子性(最重要的特性),能解决的问题就是批量执行SQL的问题
把多个SQL打包成一个整体,不能再拆分
2.一致性
描述的是,事务执行前和执行后,数据库中的数据都是合法状态,不会出现不合法临时结果的状态
3.持久性
事务执行完毕之后,就会修改硬盘上的数据,事务都是持久生效的,存储在硬盘当中
4.隔离性:
描述了多个事务并发执行的时候,相互之间产生的影响是怎样的,MySQL是一个客户端-服务器结构的程序,一个服务器通常会给多个客户端提供服务,因此很可能,这多个客户端,就同时给这个服务器提交事务来执行.与之相对的,服务器就需要同时执行这多个事务,此时就是并发,此时如果这些事务同时执行,恰好也是针对同一个表,进行一些增删查改,此时就可能会引入一些问题{
并发执行事务的过程中涉及到的三个问题
1.脏读:
如果事务A和B并发执行,其中A事务在针对某个表进行数据修改,A执行过程中,B也读取表中的数据,当B读完之后,A把表中的数据改成其他,这就导致B读到的数据不是正确的数据,把这个数据称为脏数据(过期的数据),简单来说就是事务B读取到事务A未提交的数据
解决方法,当事务A对表中的数据进行修改时,事务B不能对表中的数据进行读取.给写加锁
2.不可重复读
事务ABC,事务A对表中的数据修改完成,事务B正在读取表中的数据,此时事务C对事务A修改的数据再次进行修改,导致事务B前后两次读取的数据不一致,这就是不可重复读问题,体现的是一个事务里多次读取的结果不一样,不能在变了,简单来说就是事务B两次对同一个表进行读取结果不一样
解决方法:当一个事务进行读取的时候其他事务不能对正在读取的数据进行修改,给读加锁
3.幻读
相当于不可重复读的特殊情况,有一个事务A在读取数据的过程中,事务B新增/删除了一些数据并没有修改数据本身的内容只是对结果集进行修改,多次读取的数据虽然内容一样,但是结果集不同,结果集不同是否是问题,得视情形而定
如何解决幻读:串行化,什么是串行化:比如一个服务器,同时提交了多个事务,但是服务器一个一个的执行事务(执行完第一个事务,执行第二个事务....)
上述这三个问题与隔离性有什么关系呢?
在MySQL中提供了四个隔离级别,可以通过配置文件来设置当前服务器的隔离级别是那个级别.设置不同的隔离级别,就会使事务之间的并发执行的影响产生不同的差别,从而会影响到上述的三个问题的情况,这四个级别可以通过手动修改
1) read uncommitted(读未提交)
这种情况下,一个事务可以读取另一个事务未提交的数据,此时就可能产生脏读,幻读,不可重复读三种问题,但是此时,多个事务并发执行程度也是最高的,执行速度也是最快的.
并发程度越高速度越快,并发程度越低速度越慢
2)read committed(读已提交)
这种情况下,一个事务只可以读取另一个事务已提交的数据(给写的操作加锁了),此时,可能会出现不可重复读,幻读的情况(脏读问题解决了),此时,并发执行程度会降低,执行速度会变慢,同时也称为事务间的隔离性提高(事务之间相互影响变小了,读取数据更准确)了
3)repeatable read(可重复读)(如果没修改默认为这个隔离级别)
相当于给读和写的操作加锁了, 可能会出现幻读的问题,但是解决了不可重复读和脏读的问题,
并发执行程度进一步降低了,并发执行速度进一步降低,事务之间的隔离性进一步提高
4)serializable(串行化)
此时,所有的事务都是在服务器上一个接一个的执行的,此时解决了脏读,不可重复读,幻读问题,并发程度最低,并发执行速度最慢,隔离性最高.数据最准确
这四种级别根据我们的需要来选择隔离级别,看需要执行速度快,还是数据比较准.准确和速度不可兼得