事务的学习笔记(一)

有一天,快睡觉了,为了巩固下数据库知识,我跟我女朋友讲了事务的概念。
她问我事务是什么?是不是所有的sql都需要事务?

事务是什么

大家都知道,比如说我们要做一件事情,一般是有多个步骤才能完成,当然单个操作的也有。
那么我的理解就是,你要做的这一件事情就是一个事务,它是由一串操作来完成的。多个操作的前后顺序就要做调度。

事务的几大特性

那么我们在做一件事情的时候,是否有时候会做到一半放弃呀,这个时候为了保证不影响别的事情,咱们要清除刚刚未完成事情所造成的影响。这就叫做回滚。
比如咱们做的事情是发邮件,在写到一半的时候,老板说取消发送这个方案,那咱们是要把刚刚写的邮件删除的。
那假如咱们把邮件发出去了,那么发邮件的事情就是做完了,也就叫做事务已经提交。
如果这时候老板叫我们取消这个方案,其实发出去的邮件如果别人看到了,其实咱们是很难消除这个影响的,也就是说,事务已经提交,不能够再撤回,这个时候咱们只能执行补偿事务,即咱们只能打电话告诉人家这个方案是不行的。

原子性

上面说的这个取消发邮件的例子,就是事务的原子性。一般来说,原子性的意思就是一个操作不可再分,就像化学里面的原子一样,是最小单位。当然原则上事务的原子性指的也是一个事务执行的时候不能被打断,要看作一个整体。那么实际上指的是事务的最终表现要么是成功的,要么是没有出现过的。因为现实中,咱们要求数据库执行的性能啥的,需要并发执行事务。

隔离性

现在咱们知道事务是会并发执行的,现在咱们来考虑一个场景:比如我要给我女朋友打钱,这个时候刚好要还贷款。假如打完钱就不够还贷款了。如果两个事务一起执行的话,很可能会出现贷款公司刚刚读出我的余额,发现够还钱,下一刹那,我就把钱打给我女朋友了,这时候可能会出现贷款也还了,钱还转了。哈哈,所以这时候就要求事务是隔离的。即Ti和Tj两个事务并发执行,但是Tj不能影响到Ti的执行,也就是说,Ti在自己执行的时候,感觉到Tj是已经执行完了,或者还没开始执行。他只看到自己在执行。

一致性

假如咱们发现,本来打算给女朋友汇2000的,结果自己账号就扣了1000,女朋友还真收到2000了,这就是事务的不一致性。不一致性是需要程序员自己去保证的。也即使说,隔离执行事务时,保证事务的一致性。按照我的理解就是,在不受其他事务的影响的情况下,你的需求是否正确执行。

持久性

假如过了几天,我女朋友告诉问我怎么还没打钱呀,小孩都喝不上奶了,那么我一查,账户上的钱确实没有打过去,但是明明记得已经打了呀,应该不是幻觉,这是数据库估计出了啥事情把我们的事务给忘记了。
就算数据库奔溃了,一旦恢复还是要记得咱们执行过的事务,这就是持久性。

事务的原子性和持久性

上面已经介绍了事务的四大特性。这里我们讲下数据库时如何保证事务的这些特性的。
数据库在执行事务之前,会把事务需要执行的操作记录到日志中,当我们回滚的时候,就可以按照日志里的记录反向执行。或者在发生故障后,可以根据日志恢复数据。
数据库是存在恢复系统的。具体的恢复策略可以在写那章的时候讲。

隔离性级别

首先讲几个概念

  • 可串行化调度
    之前咱们已经说过调度,串行话调度其实就是交换两个事务之间的调度顺序,使其达到串行执行的目的。
  • 可恢复调度
    前面我们已经说过,事务提交后时很难恢复的。A事务在操作B事务更行的数据后,立马提交,然后B事务出了故障开始回滚,那么A事务依赖B事务的修改其实是不存在的。
    所以一个可恢复的调度应该是,A事务做了修改,B事务依赖这个修改,那么必须在A事务提交后B事务才能提交。
  • 无级联调度
    假设B调用了A正在修改的数据,然后C调用了B正在修改的数据,那么当A出错回滚的时候,B和C也都要回滚,所以我们需要等A提交了再调用A的数据。这样就不会有级联调用了。
隔离性分为4个级别:
  • 可串行化
    可串行化调度
  • 可重复读
    在一个事务中,任何两次读取同一个数据源时,数据是一样的。
  • 已提交读
    在读取别的事务操作的数据之前,那个事务必须时已经提交的。
  • 未提交读
    在读取别的事务操作的数据之前,那个事务没有提交也可以。

下面我们看下,为什么会出现上述这4个级别。
可串行化调度基本上是没有并发的,类似与一个cpu利用不同时间片执行不同任务一样。
可重复读是mysql默认的隔离级别,意思是再同一个事务中,不论何时两次读取同一个数据应该都是一样的。为什么会有这样的需求,我们看下面的。
已提交读,其实也是不可重复读。即要读某个数据之前,操作它的那个事务必须是已经提交了,这样可以避免脏读,但是是不可重复读,因为当我读完之后,别的事务就可以改变我的数据,那么下次读数据就是不一样了。下面我们来举一个例子:
假如你正在看作业题目,第一次看的时候是要求A+B的值,等你在想的时候,题目变成A-B的值,这时你是不是会觉得见鬼了呢?
所以不可重复读是会造成事务不一致的。
未提交读很明显,会发生脏读,比如事务随时可能会回滚,咱们很可能读了不存在的数据。

你可能感兴趣的:(事务的学习笔记(一))