数据库事务(transaction)是数据库的特性之一,在mysql数据库管理系统中,事务的管理是由引擎innordb实现的.
数据库事务可以理解为一个阶段中的活动,对于每一个窗口都有一个日志,日志中记录着本次事务中进行的改动(注意只是改动,查询不算).其中的两个指令commit,以及rollback都是将日志清空
commit:提交以后,清空日志,并把日志修改的内容进行持久化保存
rollback:清空日志,但是不会保存日志修改的内容,会回到事务开始之前的状态
(注)在mysql中,事务是默认提交的,如果想要使用可控的事务,需要使用
start transaction
来开启一个指令,然后使用commit或者rollback来结束事务
transaction
(事务) 事务有四种隔离等级,这个隔离等级指的是,在进行并发访问的时候,读取到数据的多少 注意,测试的时候尽量让两个事务全都关闭自动提交,会更加明显一点
1.read uncommitted
:可以读取非提交的内容 例如事务a,刚刚完成了一个DML操作但是还没有commit,这个时候另一个事务b是可以select到这个数据的 几乎可以认为是没有任何隔离,完全同步
2.read committed
:读取提交内容 顾名思义,只有完成了提交,才能在别的事务里面查询到 例如事务a,刚刚完成了一个DML操作但是还没有commit,这个时候另一个事务b是查不到这个数据(a自身可以) 除非是a进行了commit,清空了这次的日志,b事务才能查询到
3.repeatable read
:可重复读取/读取的是幻影数据 比如事务a在进行着各种增删改的操作,这时候事务b开始,读取数据 会发现无论a怎么改动怎么提交,b所能查询到的仅仅是b在start的那一瞬间,a已经commit的数据 要想b读到新的数据,就要停止b事务,然后重开b事务 举个例子就是:每天晚上五点钟银行查库,职员们统计这个时间点的钱数,如果在这之后有人来存钱取钱 职员们统计的数字都不会变化(废话,一变全都乱套了)
4.serializable
,序列化 你不允许参加impart
另外补充,mysql,oracle等dbms的默认事务隔离等级是read committed
隔离等级的修改方法为:
进入mysql的ini文件中找到transaction-isolation=?,修改隔离等级
修改当前会话(窗口)隔离级别: 使用语句set session transaction_isolation ='level';
修改当前系统隔离界别:使用语句 set global transaction_insolation='level';
隔离等级在修改的时候要大写
获取事务隔离等级 select @@global.transaction_isolation(系统)
获取事务隔离等级select @@session.transaction_isolation;(当前会话)
这个情况通常发生在两个窗口同时访问数据库的时候
如果都没有发生修改操作,仅仅是查询一些数据,则不会有任何影响
只有一方要修改数据的时候也是一样
但问题就出在,如果两个窗口都想要修改数据,怎么办
众所周知,每个窗口都自带一个窗口管理日志,在窗口单独进行commit和rollback的时候,都不会影响到彼此的窗口
但如果一个窗口中进行了一次修改操作,则另一个窗口执行该操作的时候,就会进入锁等待状态(阻塞状态)
所谓锁等待状态,就是将要执行的指令暂时挂起在日志区中
等到另一个窗口完成了当前事务,才会继续执行这个指令,具有延时性
举个例子(假设AB两个窗口此刻都开启了事务)
简而言之就是:当修改内存冲突的时候,会先把命令挂起,等待其他窗口修改并且完成提交以后,才能进行这个指令的草坪做
并且再挂起的阶段中,无法再该窗口执行指令
其实做一做go语言的开发就能发现,这其实就是lock,或者叫临界区的操作
暂时阻塞其他窗口的动作,但不是屏蔽