概述
什么事务:是一个不可分割的可执行逻辑单元(有好多操作,要不这些操作同时成功,要不同时失败) 事务的特性(ACID): ①原子性 让命令处在同一事务之下 ②隔离性 开始事务 ③一致性 事务回滚 ④持久性 事务提交 注意:事务一旦提交与回滚事务就结束
事务的隔离级别详解
事务的隔离性是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰。也就是说,不同的事务并发操作相同的数据时,每个事务都有各自完整的数据空间。
一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的。
隔离级别
-
读未提交(Read Uncommitted);
-
读已提交(Read Committed)
-
可重复读(Repeatable Read)
-
串行化(Serializable)
读未提交
最低级别的隔离级别。一个事务可以读取其他事务尚未提交的数据,可能导致脏读(Dirty Read)问题。
A事务 | B事务 |
---|---|
开启事务 | |
开启事务 | |
读取值1 | 读取值1 |
把值1改值2 | |
读取值2 | |
提交事务 | |
读取值2 | |
提交事务 |
这个时候会产生脏读:一个事务读到另一个事务未提交的更新数据
读已提交
要求一个事务只能读取其他事务已经提交的数据。这可以避免脏读问题,但可能出现不可重复读(Non-repeatable Read)问题,即在同一事务中多次读取同一行数据时,得到的结果可能不一致。
A事务 | B事务 |
---|---|
开启事务 | |
开启事务 | |
读取值1 | 读取值1 |
把值1改值2 | |
读取值1 | |
提交事务 | |
读取值2 | |
提交事务 |
这个解决了所谓的脏读问题,但是出现了新问题,那就是不可重复读。
可重复读
要求在同一事务中多次读取同一行数据时,得到的结果始终一致。其他事务对数据的修改不会影响当前事务的查询结果。这可以避免不可重复读问题,但可能出现幻读(Phantom Read)问题,即在同一事务中多次查询时,结果集的行数可能不一致。
A事务 | B事务 |
---|---|
开启事务 | |
读取一条数据 | 开启事务 |
插入一条 数据 | |
读取一条数据(B事务未提交看不到) | |
插入一条数据 | |
提交事务 | |
提交事务 |
事务A并不知道事务B插入了主键值为1的数据,所以自己也去插入,这个时候其实已经有了,仿佛凭空产生出现了幻觉,从而发生了错误,会产生幻读
串行化
最高级别的隔离级别。要求事务串行执行,确保每个事务读取的数据都是最新的,并且事务之间相互不干扰。这可以避免脏读、不可重复读和幻读问题,但并发性最低。也就是加锁
可能导致的问题有
1.脏读: 一个事务读到另一个事务未提交的更新数据。
2.不可重复读: 一个事务两次读同一行数据,可是这两次读到的数据不一样。
3.幻读: 一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
悲观锁和乐观锁
悲观锁:做什么事都怕有错,做什么事都要加锁
乐观锁:什么事都不会出错,根据id号进行操作
事务的分类
-
自动提交事务:每条sql都是一个事务,会自动打开事务,会自动提交事务
-
显式事务:每次都要有手动打开 提交/或者回滚
-
隐式事务:自动打开事务,手动提交/回滚
设置事务方式
set completion_type=0;自动自提交事务 set completion_type=1;手动提交事务 set completion_type=2;手动提交事务,抛异常,与服务器断开
-
开始事务
begin/begin work/start transaction
-
提交事务
commit/commit work;
-
回滚
rollback/rollback work;
-
保存点
savepoint a;
-
回滚到某保存个点
rollback to a;
案例1:
set completion_type=1; begin; insert into dept values(50,'市场部','郑州');
案例2:
set completion_type=1; begin; insert into dept values(50,'市场部','郑州'); commit;
案例3:
set completion_type=1; begin; insert into dept values(50,'市场部','郑州'); rollback;
案例4
begin; insert into dept values(50,'市场部','郑州'); SAVEPOINT a; insert into dept values(60,'教质部','郑州'); SAVEPOINT b; rollback to a; commit;
数据库的设计
良好的数据库设计
-
节省数据的存储空间
-
能够保证数据的完整性
-
方便进行数据库应用系统的开发
糟糕的数据库设计:
-
数据冗余、存储空间浪费
-
内存空间浪费
-
数据更新和插入的异常
数据库设计的步骤
收集信息 发现实体 发现实体属性 发现实体之间关系
e-r(entity relaction)图
矩形:实体 椭圆:属性 菱形:关系
映射
一对一
一对多
多对一
多对多
三大范式
一原子性:字段数组长度一样,每个单元格数据不能再分割,
二:非主键字段要完全依赖依赖主键字段/非主键字符不能部分依赖主键字段
三:非主键字段不能传递依赖主键字段