数据库事务隔离级别

一、什么是事务 ?

事务由单独单元的一个或者多个sql语句组成,在这个单元中,每个mysql语句时相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条sql语句一旦执行失败或者产生错误,整个单元将会回滚,也就是所有受到影响的数据将会返回到事务开始以前的状态;如果单元中的所有sql语句均执行成功,则事务被顺利执行。

二、事务的特性(ACID)?

  1. 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
  2. 一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
  3. 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
  4. 持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

三、事务的隔离级别?

  1. 串行化(Serializable)
  2. 可重复读(Repeated Read)
  3. 读已提交(Read Committed)
  4. 读未提交(Read Uncommitted)

mysql中默认的事物隔离级别是 2
oracle和sqlserver中默认的事物隔离级别是3
事物级别越大 效率就越差 所以我们开发的话建议事物的隔离级别 在3这里去实现
数据库锁包括:表锁、行锁,一般我们用的都是行锁。他们都是悲观锁。
2,3,4分别都是在读或者写的时候加的是 行锁

1.串行化解读

数据库事务隔离级别

打个比方, 比如我在上面这个数据库中去访问某个表 我事务 1去读了,恰巧 事务 2也来读这个表的某个内容了,如果事务1还未释放,那么事物2就是一个等待的状态 ,直到事务1执行完成并且释放。
Redis使用的就是这种串行化事务

2.可重复读

数据库事务隔离级别

从上图中我们可以看出,当我们操作数据库 用事务1来进行读取数据库内容时,事务2是可以读取到数据库的内容的,让我们看第二个图 当事务1去执行写的操作的时候,这个时候事务2是不可以读也不可以写的。
什么情况下会出现幻读呢?
举例例子:假设现在我们要去查询数据库中 age=10的数据 当我用事务1去查询数据库的时候查询到了5条记录,这时候事务1已经释放了,然后事务2去插入了一个 age=10的数据,当我们再次去执行事务1的时候 这个时候就查询到了6条记录,两次查询的结果不一样了,这就是幻读。

3.读已提交(一般我们开发尽量把事务保持在这个级别)

数据库事务隔离级别

从上图中,可以看出 当事务进行读的时候,另一个事务是可以进行读、写的。当事务进行写的时候 另一个事务是什么都不可以干的,这种情况下也是会出现幻读的。

4.读未提交

数据库事务隔离级别

从上图中,可以看出 当事务1进行读操作时候,事务2是可以进行读和写的,当事务1进行写操作时候,事务2是可以来进行读的 这种情况下会出现脏读
什么情况下会出现脏读呢?
比如说 我们要修改库存 事务1在修改库存,这个时候事务2来读取这个数据了,事务1还没有修改呢,读到了未修改前的数据,也就是说,事务1修改了,但是事务2并没有读取到事务1修改了的数据,这就导致了脏读。