说起数据库的隔离方式,首先回答下为啥会有数据库的隔离。提到隔离,那隔离是什么意思呢,简单来说就是你看不见我,我看不见你。比如澡堂里洗澡的时候,通常两个龙头之间会有一个不透明的玻璃墙及一块门帘,两个人洗澡的时候,不用坦诚相对。这个是澡堂里面的隔离,被隔离的对象是两个洗澡的人。那数据库场景的隔离以及被隔离的对象又是什么呢?我们说数据库里面被隔离的对象,是指两个正在准备操作数据库的连接,数据库场景的隔离,其实就是针对这两个连接的隔离。
两个连接为啥要隔离呢?很简单,两个连接都是操作同一个数据库,但是两个连接可能希望彼此之间的操作互不影响。同时,这些连接本身可能正在做一些复杂的事情,比如需要完成同时对数据库完成A,B,C三个操作后,这三步操作成功完成后,才算真正的操作完成。上文中A,B,C三个操作,对连接而言,它希望这三个操作是个整体,要么全部完成,要么完不成。因此需要一个术语,来指代A,B,C三个操作,当然这里也A,B,C只是代指,也有可能是A,B操作,或者A,B,C,D等等,那这个术语就叫做事务。
事务就是操作数据库的逻辑工作单位。基于事务的概念,可能总结出事务的特性,第一,事务是原子的,对外部而言,事务要么成功,要么失败,不需要关心事务内部的一系列相关操作。第二,事务是隔离的,两个连接可以各自开启各自的事务,互不干扰。 第三,事务是持续的,这里的持续是指,事务完成后,因该事务造成数据库的变动是永久的,其改动不随事务的结束而滚回改动前的墨阳。第四,事务执行前后,其状态必须是一致的,怎么定义状态呢,比如A、B两个账号转钱,A给B转100块,转账钱A有100块,B没有钱。转账是个事务,该事务需要先将A的钱扣掉,再将B的钱加上,完成这两步,则事务算是成功的,任何中间状态的失败,该事务都不能成功,不成功的话,再去查数据库的时候,A账户需要依然是100块,B账户需要是0, 成功的话,A账户需要是0,B账户需要是100块。这样才叫前后一致。 一致性需要同原子性,隔离型,持续性来保证。
说了那么多,还是回到中心议题。隔离。 数据库的隔离方式有哪些呢? 通常来说,有四种,即Read uncommitted, read committed, repeatable read, serializable。
Read uncommitted。 拿mysql为例,开两个终端,在终端上开mysql客户端,在Read uncommitted场景下,A, B两个终端同时开启事务, B更新了一条记录但不提交,A直接select的话,能看到B的更新结果, 假设B撤回了提交,对于A来说,除非A重新再select,否则之前的select结果就是脏读,因为读到了一条临时记录。

##A,B两个client均需要执行
 set autocommit=0;##mysql默认自动提交,需要先关闭
 set session transaction isolation level read uncommitted;
 start transaction;##开启事务就是指执行这一条
 ##XX操作;
 commit;##事务执行完毕的代码

Read committed。 拿mysql为例,开两个终端,在终端上开mysql客户端,在Read committed场景下,A, B两个终端同时开启事务, B更新了一条记录但不提交,A直接select的话,看不到B的更新结果。 假设B提交了结果,A再select,能看到B的提交结果。因此从A的角度,它不知道有个连接B也在操作数据库,所以在A看到,前后执行两遍select,得到的结果不一致

##A,B两个client均需要执行
 set autocommit=0;##mysql默认自动提交,需要先关闭
 set session transaction isolation level read committed;
 start transaction;##开启事务就是指执行这一条
 ##XX操作;
 commit;##事务执行完毕的代码

Repeatable read。 拿mysql为例,开两个终端,在终端上开mysql客户端,在Repeatable read场景下,A, B两个终端同时开启事务, B更新了一条记录并提交,A在B更新前后执行两次select,查出的结果完全一致,即A当前事务下,不会看到B做的一系列更新。假设B插入一条数据。由于A看不到B的更新,所以A想插入和B相同的插入数据时,会提示记录已存在。此时A就觉得,见了鬼了,我明明查出来没有这条记录。

##A,B两个client均需要执行
 set autocommit=0;##mysql默认自动提交,需要先关闭
 set session transaction isolation level read committed;
 start transaction;##开启事务就是指执行这一条
 ##XX操作;
 commit;##事务执行完毕的代码

这里提一句, B在事务中,insert之后,但不提交,此时A不能执行insert操作,必须要等B提交完才能操作;B在事务中,如果执行delete,则必须等Acommit,否则会一直等待直到超时。A在事务中,执行select不需要等待,但是执行insert或者update时,必须要等待B commit后,否则一直等待直到超时。 这里insert,delete,update操作需要等,特指A,B针对同一条记录做上述操作时。
Serailizable。 拿mysql为例,开两个终端,在终端上开mysql客户端,在Serailizable场景下,A, B两个终端同时开启事务, A,B做任何操作,均需要等待对方结束事务,否则一直等到超时

##A,B两个client均需要执行
 set autocommit=0;##mysql默认自动提交,需要先关闭
 set session transaction isolation level serializable;
 start transaction;##开启事务就是指执行这一条
 ##XX操作;
 commit;##事务执行完毕的代码