**

因为本人之前一直写的是电子笔记,对自己学会的东西作一个总结,所以基本都是文字,本来想全发成博客的形式,发现全发成博客比较花费时间,而且一直发博客质量不是很好,而且通过发博客学到的东西也会变少,所以准备先把笔记发出来,后续再将它们改成博客的形式,争取2天至少改一篇博客,觉得我总结的还行的可以先关注我,后续会发成博客形式,内容也会更加完善

**

事务:
在mysql中有一个事务处理的机制,它是为了保证我们数据的安全而开发的机制,一般在处理数据库时,可能不只一个人在操作数据库,可能很多人一起操作数据库,甚至同时操作一张数据表,这时多用户对同一数据的不同操作,很可能引发数据的安全问题,就像linux中的多线程一样,对同一份数据的临界的操作是很危险的,所以事务处理机制就是用来解决这种问题的,而事务是指在进行数据库操作时,进行的一组操作,也就是执行多个shell,这一组操作要么全部执行成功,要么全部执行失败,这就是事务,所以事务每进行一组操作,就需要提交一次,保证一组操作真正被执行
为什么事务需要全部执行成功,不然就失败,那是因为这样才能保证数据的安全,举个例子来说,我现在准备在微信上发100元的红包,给我的儿子作为压岁钱,然后我执行了发红包的操作,然我这边已经显示红包发出去了,并且也把我的钱扣了,但是由于这段时间微信出了bug,我儿子在接收红包时程序出错了,所以并没有收到我发的红包,所以相当于我的钱不见了,那这样是不是就很不好,按理来说我儿子接收不到红包,我这边应该不能发送过去,所以我发送红包的操作也应该是失败的,但是现在我发送红包的操作成功了,但接收的时候出错了,这样就很不好,所以事务处理要求要么全部执行失败,要么全部执行成功,保证了这一组操作对应要完成的功能,能够正常完成
在使用事务处理时,要注意innoDB支持事务处理,而MyISAM不支持事务处理,相当于每个操作在执行后,都会进行提交,这种提交方式称为自动提交,在使用innoDB时,如果没有开启自动提交,那么它的状态是OFF(0),如果开启了自动提交,那么它的状态为ON(1),可以使用“select @@autocommit;”这个语句来查看是否开始了事务处理,也可以使用“select autocommit = 0或者select autocommit = 1”来设置是否开启自动事务处理
mysql中事务处理详解
事务的ACID特性:
事务处理为了保证数据库使用的安全性,建构了事务的几种特性,来保证事务处理的正确性和安全性,所以事务处理都应符合以下的几种特性
1、原子性(atomicity):原子性说的就是一个事务是由好几个shell构成的,这些shell就像是一个整体,只有全部执行成功才能完成这个事务,所以这些shell就像是一个原子,不能够被分离,要么全部执行,要么一个都不执行
2、一致性(consistency):一致性说的是数据库事务操作的结果,必须由一个一致性状态,变换到另一个一致性状态,当数据库中只包含事务成功提交的结果时,数据库处于一致性状态,这时属于变换到了一个一致性状态,或者是全部执行失败,属性没有变换状态,不一致状态举个例子来说就是,正在执行一个事务时,如果突然退出了数据库,那么之前所做的操作已经改变了数据,而后面还有操作没有执行,所以就会出错,所以一致性是用原子性来保证的
3、隔离性(isolation):隔离性是指,同时执行的多个事务之间是互不影响的,做一个事务的内部操作对其它事务来说就是隔离的(也就是在这个事务还没提交以前,别的事务是不能看见它对数据库的更改的),也就是并发执行的事务之间不能看到对方的中间状态,也不能影响对方
4、持久性(durablity):持久性是指,在一个事务执行完成,然后进行提交,当提交完成后,就说明这个事务真正的执行完了,它所更改的数据全部都会改变,并且不能再恢复
处理事务时可能出现的问题:
1、脏读:脏读是指没有进行隔离的两个事务之间的错误,具体意思是,第一个事务正在进行处理,并且更改了数据,但这个数据并没有提交到数据库,而第二个事务在执行时,读到第一个事务还没有提交的数据,这样就产生了脏读(也就是读到了未提交的数据),这样是极其容易引发错误的,因为第一个事务还没有提交,可能还会重新改数据,所以第二个事务读的数据,不能算是一个正确的数据,举个例子来说就是,charles的原工资为1000,财务人员将charles的工资改为了8000(但未提交事务),charles读取自己的工资 ,发现自己的工资变为了8000,欢天喜地,而财务发现操作有误,回滚了事务,charles的工资又变为了1000像这样,charles记取的工资数8000是一个脏数据;要解决这个问题,就需要使用隔离性
2、不可重复读:它是一个由于多个执行流对同一资源访问而造成错误的问题,具体意思是,第一个事务正在处理它的shell,这时它需要对数据库中的数据进行读取(这是第一次读取),然后读取到了自己想要读取的内容,但是这时第二个事务执行完毕,提交了任务,并且它修改了第一个事务读取的数据库资源,这时还没有出现问题,但是因为第一个事务还没有执行完毕,也就是没有提交,可能继续执行程序,如果第一个事务这时,又准备读取刚刚的资源,就出现问题了,因为第二个事务已经更改了那份资源,当第一个事物再去读取时,发送它第二次读取的数据和第一次读取的数据不同,所以这时出现了错误,这就是不可重复读的错误,因为第二个事务在第一个事务执行过程中修改资源而造成,第一个事务读取的错误;举个例子来说就是,在事务1中,charles读取了自己的工资为1000,操作并没有完成,在事务2中,这时事务人员修改了charles的工资为2000,并提交了事务,在事务1中,charles再次读取自己的工资时,工资变为了2000;要解决这个问题,只有在修改的事务完全提交时再读,才不会出错,或者是不要读取数据库
3、幻读:它和不可重复读的问题很像,但又不是同一问题,它也是多个执行流对同一资源访问而造成错误的问题,具体意思是,第一个事务正在处理它的shell,这时它需要对一个数据表的数据进行修改,这种修改波及所有的行,然后它根据shell修改了所有的行(还没有提交),这时第二个事务又执行了一个shell,这个shell的作用是给刚才第一个事务修改的数据表增加一行,增加完成后,它就提交了,这时第一个事务发送数据表中又多了一行没有修改,就好像出现幻觉一样,举个例子来说就是,事务1,读取所有工资为3000的员工,这时事务2向employee表插入了一条员工记录,工资也为3000,事务1再次读取所有工资为1000的员工 共读取到了11条记录;解决它的办法就是,不要在第一个事务处理完成之前,不要添加或删除数据
幻读和不可重复读的区别是,不可重复读是指偏重对数据表的修改,两次读到的数据不同,而幻读是指在数据表中的新增或删除,对原有数据并没有影响
数据的分离级别:
因为事务中可能出现上述的错误,所以mysql提供了分离级别的机制,分离级别越高避免上述错误的的机率就越高,不过分离级别越高,处理的速度就会越慢
1、read uncommited(读未提交):如果将分离级别设置为它,说明允许上述的所有错误发生,也就是脏读、不可重复读、幻读的错误都可能会发生,不过它的处理速度最高
2、read commited(读已提交):如果将分离级别设置为它,就表示脏读的错误不会发生
3、repeatable read(可重复读):如果将分离级别设置为它,就表示脏读和不可重复读的错误不会发生
4、serializable(可串行化):如果将分离级别设置为它,就表示脏读、不可重复读、幻读的错误都不会发生,不过它的处理数据的速度是最慢的
mysql中事务处理详解
mysql中默认的分离级别是repeatable read,表示只允许发生幻读,如果要查看当前事务的分离级别可以使用“select @@tx_isolation;“语句
mysql中事务处理详解
如果要设置分离级别,可以使用set关键词,使用方法为”set session transaction isolation level 分离级别“,例如我要将分离级别设置为serializable,可以这样写”set session transaction isolation level serializable“
mysql中事务处理详解
分离级别是使用锁定来防止那些错误的,锁定时有二种类型,一种是共享锁定,将对象数据变为只读形式,不能进行更新,所以也成为读取锁定,一种是排他锁定,当执行insert/update/delete的时候,其它事务不能读取该数据,因此也成为写入锁定,这种锁定可以针对一条记录,也可以针对一张数据表,甚至可以针对一个数据库
使用事务处理:
如果要使用事务处理,就要用start关键词,使用方法是输入”start transaction“,这样就代表着一个事务的开始
mysql中事务处理详解
然后我们就可以输入shell了,当我们在使用shell,发现不小心修改数据了,因为我们还没有提交,这时我们就可以回到初始状态,例如我有如下一张数据表:
mysql中事务处理详解
现在我要修改food对应的leader字段的数据为”miss“,可以输入”update school set leader = ‘miss’ where college = ‘food’;“
mysql中事务处理详解
但是现在又发现我修改错了数据,想要返回起始状态,可以进行回滚,输入”rollback“关键词
mysql中事务处理详解
不过使用rollback,只能回到起始状态,如果我们这一组事务中有很多shell,我们想回到的状态不是起始状态,而是中间的某一状态,这时只使用rollback就会显得很麻烦,所以mysql中提供了一个保存点的功能,也就是我们可以在进行事务的过程中设置不同的保存,让我们可以回到不同保存点时的状态,设置保存点的关键词是”savepoint“,使用方法是“savepoint 保存点名字”,例如我要设置一个保存点,名字为“first”
mysql中事务处理详解
如果我们想回到这个保存的状态,可以使用“rollback to savepoint 保存点名字”的方法,如果我们的事务已经将shell全部执行完了,也就说明事务结束了,这时我们就可以提交事务,真正的修改数据了,这时可以使用关键词“commit”

mysql中事务处理详解

相关文章: