1. 数据库事务4大特性(ACID),
数据库事务4大特性(ACID):
1.原子性(Atomicity):
事务中一系列对数据库的操作要么全部成功,要么全部失败,如果成功就要全部应用到数据库,如果失败则不能对数据库造成任何影响
2.一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另一个一致性状态(转账举例,两个账号转账前和转账后总金额数目不变)
3.隔离性(Isolation)
多个并发事务相互隔离,数据库为一个用户开启的事务不能被其他事务的操作干扰,数据库引擎提供了多种隔离级别来保证事务隔离性
4.持久性(Durability)
一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作
2. 数据库事务隔离级别
事务隔离级别由数据库引擎实现,由低到高依次为Read uncommitted(读未提交)、Read committed(读提交)、Repeatable read(可重复读)、Serializable(序列化),这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题
1.脏读
一个事务处理过程中读取了另一个事务中还未提交的数据:
事务A:
update account set money=money + 100 where name=’B’; (此时A通知B查看账户)
update account set money=money - 100 where name=’A’;
事务B:
select money from account where name=’B’; (B被通知查看账户)
如果事务A最终操作不成功回滚,但B读取了修改后的账户金额(此为脏数据),即为脏读
2.不可重复读
事务A多次修改并最终提交了数据,事务B在事务A提交前读取了一个数据,在事务A提交后又读取了一个数据,两次数据不一致,即为不可重复读的问题。和脏读的区别是,不可重复读问题是读取的另一事务已提交的数据
3.幻读(虚读)
事务A对数据库中所有记录都进行了修改,但这个过程中事务B向表中插入了一条数据,事务A执行完成后发现数据库中有一条数据未被修改,就好像发生了幻觉一样,即为幻读
MySQL数据库为我们提供的四种隔离级别:
① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
③ Read committed (读已提交):可避免脏读的发生。
④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
隔离级别越高,执行效率越低,例如Serializable使用锁表的方式达到了最高的隔离级别;记得设置数据库的隔离级别一定要是在开启事务之前
3. 设置数据库隔离级别
- 在MySQL数据库中设置事务的隔离 级别:
set [glogal | session] transaction isolation level 隔离级别名称;
set tx_isolation=’隔离级别名称;’
- 通过JDBC设置数据库隔离级别
调用Connection对象的setTransactionIsolation(level)可设置当前链接的隔离级别,具体level设置如下:
TRANSACTION_NONE: 指定该链接不支持事务
TRANSACTION_READ_COMMITTED: 指定该链接的操作为读可提交,可解决脏读
TRANSACTION_READ_UNCOMMITTED: 指定该链接的操作为读未提交,隔离等级最低
TRANSACTION_REPEATABLE_READ: 指定该链接操作为可重复读,可解决脏读和不可重复读
TRANSACTION_SERIALIZABLE: 指定链接为序列化,最高隔离等级
对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。
4. sql依赖关系
- 函数依赖:关系型数据库中有属性集合X,属性集合Y,若X中的元素能够唯一决定一个Y,则Y依赖于X,记为X -> Y
- 完全函数依赖:X -> Y且对于任意X的真子集Z都存在Z !-> Y(即X所有元素才能唯一决定一个Y,X中的部分元素无法唯一决定一个Y),则称为Y对X的完全函数依赖
- 部分函数依赖:Y完全函数依赖于X的真子集Z,则Y部分函数依赖于X
- 传递函数依赖:X -> Y, Y -> Z, 且Y不是X真子集,Z不是Y真子集,Z不是X真子集,X不依赖于Y,则Z传递函数依赖于X
- 平凡函数依赖:X -> Y且Y是X的真子集,则Y平凡函数依赖于X
- 非平凡函数依赖:X -> Y且Y不是X的真子集,则Y非平凡函数依赖于X
5. sql范式
关系型数据库的范式是制定二维表的标准和依据
- 1NF:表中的每一个属性都是原子属性(不可分割的数据项),非主属性对主属性存在部分或者完全函数依赖
- 2NF:在1NF的前提下,每一个非主属性对于主键都是完全函数依赖的,但属性之间存在传递函数依赖
- 3NF:在2NF的前提下,每个属性之间不存在传递函数依赖,即属性与属性之间基本独立
- BCNF:在3NF前提下,表中只有一个候选键,没有多余候选键
6. mysql事务的redo和undo机制
事务常说一系列操作作为一个整体要么都成功要么都失败,主要特性acid,事务的的实现主要依赖两个log redo-log,undo-log,每次事务都会记录数据修改前的数据undo-log,修改后的数据放入redo-log,提出成功则使用redo-log 更新到磁盘,失败则使用undo-log将数据恢复到事务之前的数据
7. Mysql锁机制
mysql的锁机制是两段锁:将事务分为加锁阶段和解锁阶段两个阶段,加锁阶段对事务进行"读"的操作之前,需要申请S锁(共享锁),对事务进行"写"的操作之前,需要申请X锁(排它锁),当事务提交之后,就会释放锁,此时事务进入解锁阶断,在这个阶段只能进行解锁操作,不能再进行加锁操作
1) 共享锁:
共享锁的代号是S,S锁的锁粒度是行或者元组(多个行)。一个事务进行读操作时可以对数据加S锁,获取了S锁之后,可以对锁定范围内的数据执行读操作,其余事务也可以获取这部分数据的S锁,但无法获取X锁(写锁)
2) 互斥锁:
互斥锁代号是X,X锁的粒度与S锁相同,也是行或者元组。一个事务获取了X锁之后,可以对锁定范围内的数据执行写操作,其余事务无法获取这部分数据的S锁和X锁
3) 乐观锁:
mysql提供了种mvcc的机制,支持乐观锁,通过版本号的方式,避免同一数据不同事务间的竞争,所说的乐观锁只在事务级别为读未提交(Read committed)和 读已提交(Read committed)才会生效,也就是说对于这两个隔离级别,mysql就是使用乐观锁的方式保证并发
4) 锁和事务隔离级别的关系:mysql就是通过锁机制来保证事务的隔离性:
- 读未提交:无论是读的操作还是写的操作,都不会进行加锁操作
- 读已提交:数据的读取操作不会进行加锁,但是数据的写入、修改和删除操作是需要加锁的,保证不会读到脏数据
- 可重复读:数据的读取操作进行加锁,保证读取数据的一致性
- 序列化:每次读取的时候事务都要获取表级别的S锁,每次写入的时候都会加写锁(X锁),读写操作会相互阻塞
5) 数据库锁和索引的关系
当加锁的语句没有涉及到该行数据的索引、指定索引不明确或者指定索引不为唯一索引,mysql会给整张表加锁,而不是给某个数据行加锁
网友评论