mysql事务

在看mysql事务的过程中,看了很多别人的优秀博客,这篇博客中大部分都是看了别人的博客把自己能够理解的给写了下来,若有错误请指正。

事务的四个条件:(ACID)

A(原子性):在一个事务里的操作,只有两种可能,一是全部顺利完成,二是全部都没完成,后者出现的情况是在执行事务中出错了,然后会回滚到事务执行前的状态。
C(一致性):在事务执行前后,数据库的完整性未被破坏,数据库的状态一定是一致的。这里抄了一段别人的话,比较好理解:对于这个概念,它的第一层意思就是对于数据完整性的约束,包括主键约束、引用约束以及一些约束检查等等,在事务的执行的前后以及过程中不会违背对数据完整性的约束,所有对数据库写入的操作都应该是合法的,并不能产生不合法的数据状态。而第二层意思其实是指逻辑上的对于开发者的要求,我们要在代码中写出正确的事务逻辑,比如银行转账,事务中的逻辑不可能只扣钱或者只加钱,这是应用层面上对于数据库一致性的要求。
I(隔离性):就是多个并发事务执行时,他们是互不干扰的,不会因为某个事务干扰到其他事务的执行结果。事务隔离的四个级别:读未提交、读提交、可重复读、串行化。
D(持久性):事务执行完后,其对数据的修改是永久的。

事物的使用:

Begin开启事务,commit提交,即执行begin到commit之间的语句。
Rollback是回滚,即回滚到事务执行前的状态,期间的任何未提交的修改都会被撤回。
Savepoint identifier,就是在事务中创建保存点。
Release savepoint identifier,顾名思义就是删除事务中的保存点。
Rollback to identifier,把事务回滚到保存点的状态。
Set transaction,设置事物的隔离级别,对应隔离性中讲到的四个隔离级别。

mysql中对执行的语句进行回滚是通过回滚日志实现的,事务进行的修改会记录在其中,之后才对数据库中的对应行写入。简单来说就是有个日志会记录你的可能会影响数据库的操作,万一有什么错误,类似于数据库崩溃阿之类的,就可以利用日志来查看事务的状态,当然我们得对日志进行持久化到磁盘上,万一重启了还能够利用日志来查看事务的状态。
利用日志回滚其实就是执行与修改相反的语句,比如记录了insert,那么则执行对应的delete,记录了update,就执行相反的update。

事物的三个状态:

执行中、执行完成、执行失败。

事务一旦提交后则不能够被回滚。如果要想回到事务提交前的状态则需要利用重做日志,在每次事务对数据进行修改时,都会生成重做日志并写入重做日志缓存,在事务被提交时,才会把重做日志缓存给刷新到重做日志文件中。

回滚日志与重做日志的区别:

回滚日志是对事务的影响进行撤销。事物的原子性与持久性就是由混滚日志保证的。
重做日志是对已经提交的事务进行重做,它能够对发生错误与需要回滚的事务进行回滚。在事务提交后若数据还没写入磁盘中发生宕机的话能够在重新启动后恢复数据。
两者合在一起就是事务日志,能进行回滚和重做。

并发事务的情况下:

若在事务并行执行的情况下,事务可能会存在一些复杂的情况,比如一个事务1对表1进行了操作,而事务2也对表1进行了操作,并且两个事务都进行了提交,若要对事务1进行回滚的话,必须先要对事务2进行回滚,因为得保持事务的原子性,这样事务2就依赖于事务1的执行,这样的回滚称为级联回滚,在这种情况下其实要利用隔离性中的锁。
隔离性的实现,就是对并发的控制,这里需要用到锁,锁一般分为读锁和写锁,比如有一个事务对数据进行修改,就会获得一个写锁,其他事务想对这个数据进行修改的话,就必须等待这个写锁释放后才行。有了锁便不会发生级联回滚了。

总结:

原子性对于事务的执行是必要的,ACID中的一致性不仅是对于数据库完整性的要求也是对开发者的逻辑设计要求,隔离性保证并发不会出现太多过错,但是完全保证隔离性的话会对性能有影响,在实际开发需求中,要对隔离性进行合适的调整,持久性保证我们的数据是持久的,不会丢失。
参考博客:https://draveness.me/mysql-transaction

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章