持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
事务的定义
维基百科的定义:事务是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由 一个有限的数据库操作序列构成。
事务的典型场景
比如下单,会操作订单表,资金表,物流表等等,这个时候我们需要让这些操作都在一个事务里面完成。在金融的系统里面事务配置是很常见的,比如行内转账的这种操作,如果我们把它简单地理解为一个账户的余额增加,另一个账户的余额减少的情况(当然实际上要比这复杂),那么这两个动作一定是同时成功或者同时失败的,否则就会造成银行的会计科目不平衡。
支持事务的存储引擎
InnoDB 支持事务。
事务的四大特性
第一个,原子性,Atomicity,也就是我们刚才说的不可再分,也就意味着我们对数据库的一系列的作,要么都是成功,要么都是失败,不可能出现部分成功或者部分失败的情况。全部成功比较简单,问题是如果前面一个操作已经成功了,后面的操作失败了,怎么让它全部失败呢?这个时候我们必须要回滚。
原子性,在InnoDB里面是通过undo log来实现的,它记录了数据修改之前的值(逻辑日志),一旦发生异常,就可以用undo log来实现回滚操作。
第二个,一致性,Consistency,指的是数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。比如主键必须是唯一的,字段长度符合要求。
除了数据库自身的完整性约束,还有一个是用户自定义的完整性。
第三个,隔离性,Isolation,我们有了事务的定义以后,在数据库里面会有很多的事务同时去操作我们的同一张表或者同一行数据,必然会产生一些并发或者干扰的操作,那么我们对隔离性的定义,就是这些很多个的事务,对表或者行的并发操作,应该是透明的,互相不干扰的。通过这种方式,我们最终也是保证业务数据的一致性。
最后一个叫做持久性,durability。我们对数据库的任意的操作,增删改,只要事务提交成功,那么结果就是永久性的,不可能因为我们系统宕机或者重启了数据库的服务器,它又恢复到原来的状态了。这个就是事务的持久性。
持久性是通过redo log来实现的,我们操作数据的时候,会先写到内存的buffer pool里面,同时记录redo log,如果在刷盘之前出现异常,在重启后就可以读取redo log的内容,写入到磁盘,保证数据的持久性。
实际上还有一个双写缓冲的机制。
因为存储引擎的页和操作系统的页大小不一致。一个存储引擎page的数据要写4次,如果中间发生异常,或造成页数据的不可用。所以,必须把页的数据备份起来,这个就是双写缓冲(double write buffer)。
手动开启事务也有几种方式,一种是用begin;一种是用start transaction。
那么怎么结束一个事务呢?我们结束也有两种方式,第一种就是提交一个事务,commit;还有一种就是rollback,回滚的时候,事务也会结束。