1.事务的什么
在学习MySQL的初期,我们通常都是一个一个sql语句的执行,但是在实际开发过程中,我们经常是多个sql语句一起执行,这种多个sql语句在逻辑上要一起执行的就可以看做是一个事务,组成这个事务的多个sql,要不就全部成功执行,要不就全部执行失败;
2.事务的四大特性
1、原子性
原子性是事务的最重要的也是最根本的性质,我们把多个操作打包成一个整体,要求这个整体的所有操作,要不就全部成功,要不就全部失败,避免了有些操作执行成功,有些操作执行失败了,从而导致产生了中间转态这样的错误的事情发生。我们就把多个操作打包成一个整体,就是事务的原子性。原子就是一个不可切割的整体。
回滚机制
事实上事务的每一句sql语句肯定都是要执行的,但是就会出现意想不到的情况,导致有些sql执行成功,有些sql就没有执行到,或者执行失败了,事务就能保证,当事务中的一条sql语句执行失败的时候,数据库就会自动把前面执行过的语句造成的影响给恢复回去,就好像事务的一句sql语句都没有执行那样,实际是数据库根据mysql的日志对数据库进行了恢复操作,我们就把数据库恢复成修改之前的样子称为回滚。
为了实现回滚机制,数据库在执行事务的时候会记录日志,并把日志写到硬盘中,如果事务执行成功,就会删除掉日志,如果事务执行失败,数据库就会根据日志的操作,把数据库恢复。
1)进行了新增的操作,就把数据库新增的数据删除;
2)进行了删除操作,就把删除的数据恢复;
3)进行了修改操作,就把修改的数据恢复;
4)进行查询操作,没有影响数据库的数据,就不进行任何操作;
2、一致性
一致性指的是事务执行前后,数据的一致性,不会出现数据对不上的情况。可以理解成对数据库进行了修改了,修改之后的数据是符合要求的,是正确的。
这也和回滚机制有关,如果事务执行失败,回滚之后的数据也是正确的,回到了事务执行前的转态;如果事务执行成功了,数据也是符合预期的,是正确的。
3、持久性
一说到持久性,就要想到把数据存储到硬盘了。这里的持久说的也是把数据的存储到硬盘上,即使程序结束,电脑关机了,数据也还存在。如果是存储在内存上,那就是不持久,会因为程序结束或者电脑关机了,存储在内存中的数据就丢失了。
事务对数据库进行的修改,数据存储到硬盘上,重启依然存在。
4、隔离性
隔离性是事务的四个特性中最难理解,说是四个中最难,但实际上也不是很难;
事务的隔离性,描述的数据库并发执行事务时候,产生的情况,数据库是支持多线程的,允许多个事务同时同时访问数据库,数据库服务器就需要把多个事务同时处理好,多个事务一起执行,就会发生以下的问题:
1)“脏读”问题
事务A正在对修改数据库中的数据,事务B就来读事务A修改后的数据,但是事务A在事务B读之后,又对事务B读取的数据库数据进行修改,这就会导致事务B读取到的数据和事务A实际提交的数据是不一样的,这个过程中事务B读取到的数据是事务A对数据库的数据修改的临时数据,而这个临时数据有可能就是错误的,我们称这种问题为“脏读”问题。
对于“脏读”问题的处理方案,数据库就是对数据库的写操作进行加锁,就是说别的事务在写的时候,你就不会对数据进行读操作。
2)不可重复读问题
有了对写操作进行加锁,我们就不能再写的时候进行读操作,那我们就可以在写操作完成对数据进行读操作,但是在读的过程中,我们可以进行写操作,这就会出现读的时候,数据发生了变化,导致开始读的时候是结束读的数据是不一样的,这就是不可重复读问题。
对于不可重复读问题,数据库的解决方案就是在进行读的时候,对读操作进行加锁,不能对数据进行写操作,这样以来就能避免不可重复读问题。
3)幻读问题
有了上面的两条规则,我们就不能在写的时候进行读,在读的时候进行写,但是如果事务A修改数据之后提交,事务B在读取数据,事务C不对B读取的数据进行修改,而是对对应的表进行增加/删除数据,这就会导致B读的数据集不一样,要先说明的是这里读的数据集原有的是一致的,就是条数多了或者少了,就是幻读问题,可以认为是不可重复读问题的特殊情况。
对于幻读问题,数据库的解决方案,就是串行化支持执行事务,也就是一个事务接着一个事务执行,这时候数据库的准确率是最高的,效率是最低的,隔离性是最高的。
四个隔离等级
那么数据库对隔离性是如何体现的呢?
mysql给隔离性提供了四个隔离等级,可以根据实际业务的需求等等,在配置文件中进行修改:
1)read uncommitted(读未提交):允许读取其他事务未提交的数据,存在脏读+不可重复读+幻读问题,效率最高,准确率最低,并发程度最高,隔离性最低;
2)read committed(读已提交):只允许读取已经提交事务的数据,对读加锁,解决了脏读问题,存在不可重复读+幻读问题,效率降低,准确率提高,并发程度降低,隔离性提高;
3)repeatable read(可重复读):对读操作和写操作进行加锁,解决了脏读+不可重复读,存在幻读问题,效率又降低,准确率又提高了,并发程度再降低,隔离性又提高;
4)serializable(可串行化):解决了脏读+不可重复读+幻读问题,效率最低,准确率最高,并发程度最低,隔离性最高。
以上的四种事务的隔离级别的选择可以根据实际业务的不同进行选择,比如要做一个跟钱相关的业务,就可以选择串行化隔离级别,以实现最高的数据的准确性,要做一个点赞的系统,就可以选择“读未提交”隔离级别,最求最大的效率等等;