事务:事务其实就是单个数据逻辑单元组成的对象操作集合,而数据库的终极目标就是使数据库从一个一致的状态转换到另一个一致的状态,这就是ACID中的一致性,原子性,隔离性,持久性是为了实现这个目标的手段。
事务的四大特性:
A:原子性(Atomicity),一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态
C:一致性(Consistency),指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
I:隔离性(Isolation),指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
D:持久性(Durability),指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。
数据库锁:
1、按级别分
共享锁(读锁):一个事务获取了一个数据行的共享锁,其他事务能够获得该行对应的共享锁,但不能获得排他锁,即一个事务再读取一个数据的时候,其他事务也可以读,但不能对数据行进行增删改。
排他锁(写锁):一个事务获取了一个数据行的排他锁,其他食物就不能再获取该行的其他锁,即一个事务再读取一个数据行的时候,其他事务不能对该数据行进行增删改查。
2、按粒度分
行级锁:开销大,会出现死锁,锁定粒度最小,发生锁冲突概率最低,并发高
#①update
mk_user
set
name
=
'1'
where
`
name
`=
'idis12'
;
#②update
mk_user
set
name
=
'12'
where
id=12;
第一条语句会优先使用`name`索引,因为name不是主键索引,还会用到主键索引,第二条语句是首先使用主键索引,再使用name索引 如果两条语句同时执行,第一条语句执行了name索引等待第二条释放主键索引,第二条执行了主键索引等待第一条的name索引,这样就造成了死锁
表级锁:开销小,不会出现死锁,锁的粒度大,发生锁冲突概率高,并发低
页面锁:会出现死锁,并发度一般
并发事务的四大问题
脏读:事务A读取了事务B未提交的数据
不可重复读:事务A在连续读的过程中事务B写入了一次,事务A前后读取的数据不一样
丢失更新:事务A和事务B均写入数据,事务A写入的数据被事务B覆盖
幻读:事务A修改数据的过程中,事务B向表中插入一条数据,A修改完后发现数据并没有被全部修改完
隔离级别
隔离性的实现主要是基于数据库锁机制来实现的;隔离级别主要分为读未提交(Read uncommited),读已提交(Read commited),可重复读(Repeatable reads),序列化(Serializable)
Read uncommited:一个事务读取到另外一个事务未提交的数据,脏读
实现原理:在事务读取数据的时候不加锁,但是在事务更新某条数据的时候,必须先对其加上行级共享锁,直到事务结束才释放
Read Commited:
读取:事务在读取数据的时候加上行级共享锁,一旦读完释放锁
更新:事务在更新数据的时候加上行级排他锁,直到事务结束才释放锁
Repeatable Read:
读取:事务在读取数据的时候,必须加上行级共享锁,直到事务结束
更新:事务在更新数据的时候加上行级排他锁,直到事务结束
Serializable:
读取:事务读取数据的时候加上表级共享锁,直到事务结束
更新:事务在更新数据的时候,加上表级排他锁,直到事务结束