MySQL数据库事务的概念及其理解。

目录

事务

回滚(rollback)

事务的使用

事务的四大特性

1、原子性

2、一致性

3、持久性

4、隔离性

事务并发编程造成的问题

1、脏读

2、不可重复读 

3、幻读问题

MySQL的四个隔离级别

未提交读(Read Uncommitted)

提交读(Read Committed)

可重读(Repeated Read)

可串行化(Serializable)


 


事务

事务就像是指令的集合一样,只有事务中的所有的操作全部都做完,这个事务才算是完成,否则就不能完成。也就是说,一个事务,其中包含的指令要么全部完成,要么就一个也不完成。在日常生活中我们经常会遇到事务操作。比如你是一名大学生,月末没钱了,现在向家里要生活费,你的父母给你转账,到你收账,其实可以分为这样的两步。

1、父母的银行账户减少了2000元。

2、你自己的银行账户多了两千元。

按照正常的逻辑来说,两步操作一前一后互不干扰,但是总会有特殊情况,当你父母给你转账的时候,你父母的账户减少了2000元之后,你自己的账户在那一瞬间冻结了,不能入账了,而你父母账户也已经减少了2000元,这个时候就会造成了不必要的损失,为了防止这些问题的出现,我们就需要引用事务这一概念来进行指令的打包。如果转钱,只有这两步操作全部完成之后才能算是完成,只要有一个发生异常,就都不能算这个事务进行完毕。


回滚(rollback)

事务是把一系列的操作绑定在一起,只要有一个操作不能正常的运行,那么其他操作也都不会执行,那么事务是如何实现这样的操作的呢?

其实事务中的多条指令并不是没有执行,事务中的指令还是按照顺序依次进行执行的,只不过事务中的指令在执行的过程当中还会存储未执行之前的状态,也就是说,当事务进行到一个异常的指令的时候,要把事务中之前已经进行过的部分全部回撤,撤回到原来的状态,修改过的数据重新改回来,经过运算的数据进行逆操作全部恢复到事务开始时候的状态。当在事务中执行到了一个异常的指令的时候,把已经进行过的操作全部撤销的过程就叫做回滚。


事务的使用

在数据库中进行指令的打包,事务操作的使用有着固定的语法规则:

(1)开启事务:start transaction;

(2)执行多条SQL语句

(3)回滚或者提交

现在我们继续用上面的例子进行演示,当我们把转账操作设置成为一个事务的时候:

start transaction;

1、小王的父母的银行账户减少2000;

2、小王的银行账户增加2000;

commit;

如果事务中的1,2条指令都能够正常的进行,那么就会执行到commit的指令,把所有事务内完成的指令提交,就算完成了一个事务。但是如果事务中1指令正常进行,2指令执行的时候出现异常,那么就会发生回滚操作,把已经执行过的1指令进行撤销,返回到未执行1指令的时候,这样就完成了回滚。


事务的四大特性

1、原子性

事务的原子性也是事务的初心和使命,事务最主要的特性也是原子性。在原子核和和核外电子未被发现之前,原子被认为是组成世界万物的最基本的元素,事务的原子性说的也就是这个意思。也就是说,事务被当作执行的基本单位。当多个指令被打包成一个事务的时候,就会体现他的原子性,本来多个指令是互不干扰的,不管另一个指令有没有正确执行,反正跟我这个指令无关,我的指令依旧会正常执行。当被事务打包之后,多个指令也就构成了一个不可分割的整体,只有全部指令正确运行完成才能是真正的完成,否则就会回滚。这就事务的原子性。

2、一致性

事务的一致性可以理解为数据从一个一致的状态转换成为另外一个一致的状态,也即是说在数据前后的完整性必须是一致的。

3、持久性

持久性意味着事务所引起的改变都是一直有效的,事务进行的操作会保存在硬盘上,即使数据库发生崩溃和障碍,修改后的数据也不会改变,保持原来的状态。

4、隔离性

隔离性指的是事务与事务之间是互相隔离的,一个事务正在执行不能被另一个事务打扰。事务的内部操作和使用其他数据对其他的并发事务是隔离的,互不影响的。        


事务并发编程造成的问题

1、脏读

脏读就是在一个事务正在处理的过程中读取到了另外一个事务未提交的数据。

举个例子

考试完成之后,老师正在进行考试成绩的录入,有一位同学因为急迫想要知道自己的成绩,所以就在老师没有提交成绩到教务系统的时候就在老师的旁边偷偷看自己的成绩,当看到自己的成绩不及格的时候,这位同学心灰意冷了离开了,可是这位同学不知道的是,老师录入完成信息之后,在提交成绩之前检查出了这位同学成绩录入错误,就更改了这位同学的成绩,导致这位同学自己读取到的成就和老师提交到教务系统的成绩是不同的,这就是脏读问题。

假如一个事务中有读取数据,修改数据,提交数据这三个指令,另一个事务有读取数据信息的作用,原本第二个事务要等到第一个事务提交数据之后再进行读取才能正确取得信息,现在第一个事务进行到读取数据的时候还未修改,第二个事务就进行读取,读取到的就是修改之前的信息,这样就造成了脏读。

解决脏读我们可以引入锁的概念,我们给写数据的事务进行加锁,也就是读事务必须在写事务进行完成之后才可以执行,这样读取出来的数据就是在提交完成之后的数据,防止以上情况的发生。

2、不可重复读 

务第一次读取与第二次读取之间数据被其他的事务修改了。不可重复读是一个事务的范围内多次查询数据库结果返回了不同的数值,这是由于在事务两次读取之间,其他的事物对数据进行了修改而造成的影响。

举个例子

上个脏读的同学由于现在老师写成绩的过程加锁了,所以只好等到老师提交成绩之后再进行读取,等到老师提交后,同学看到自己的成绩位列第一,非常的开心。可是由于同学的读的过程没有加锁,老师依旧可以修改,老师提交成绩后又发现这位同学的成绩有误,所以老师就在同学读取成绩的过程当中进行修改,而这位同学因为多次老师的多次修改而读取的成绩数据不一样,就发生了不可重复读的问题。

一个事务正在读的过程中如果另一个事务对正在读取的数据进行更改操作,导致两次读取出来的结果不一样就会造成不可重复读的问题。

解决这一类问题我们需要给读操作加锁,也就是说在读的过程中就不能进行写数据,保证了我们读取的数据的准确性。

3、幻读问题

当我们给写操作和读操作都进行了加锁之后,指的是在同一个java文件中两个事务不能同时进行写和读的操作,那么如果一个文件中已经有了一个读的事务在进行,另一个写的事务就不能在对这个文件进行操作,但是它可以对其他的文件进行写操作,这就会造成幻读的问题。

事务1查询一个范围,事务2又在该范围内插入了新的满足条件的记录,那么事务1再次进行查询之后就会产生新的满足条件的记录。

解决幻读的问题就是让事务之间完全舍弃并发,实行串行化。


MySQL的四个隔离级别

未提交读(Read Uncommitted)

一个事务能够读取到别的事务中没有提交的更新数据。事务中的修改,即使没有提交,其他事务也可以看得到。在这种隔离级别下有可能发生脏读,不可重复读和幻读。

提交读(Read Committed)

一个事务只有进行提交之后才能被其他的事务读取,这种的隔离级别下可以解决脏读问题,不能解决不可重复读和幻读的问题。

可重读(Repeated Read)

保证了同一事物中先后执行的多次查询能够返回同样的结果,,看到的每行的记录都是一样的,不受其他的事务影响,但是不能解决幻读问题。

可串行化(Serializable)

不允许事务之间并发执行,读和写是彻底的隔离开的,在读取的每一行数据上都加上锁,读写之间会相互阻塞,这样的效率是很低下的,这种隔离级别是最高的,也是最安全的,就像是两台ATM不能同时登录一个账号一样,可以解决脏读,不可重复读和幻读的问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值