MySQL学习笔记 - ShaneChan/MySQL GitHub Wiki
第三章
事务
事务的概念
事务是访问并可能更新各种数据项的一个程序的执行单元.事务由begin transaction和end transaction之间执行的全体操作组成.这些步骤的集合必须作为一个单一的、不可分割的单元出现.
事务的四个特性:
- 原子性(atomicity):事务的所有操作在数据库中要么全部正确反映出来,要么完全不反映,即所有操作要么全部执行,要么根本不执行.因此,如果一个事务开始执行,但是由于某些原因失败,则事务对数据库造成的任何可能的修改都要撤销.
- 一致性(consistency):隔离执行事务时(换言之,在没有其他事务并发执行的情况下)保持数据库的一致性.这种一致性是指如果一个事务作为原子从一个一致的数据库状态开始独立地运行,则事务结束时数据库也必须再次时一致的.
- 隔离性(isolation):尽管多个事务可能并发执行,但系统保证,对于任何一对食物T1和T2,在T1看来,T2或者在T1开始之前已经完成执行,或者在T1完成之后才开始执行.因此,每个事务都感觉不到系统中有其他事务在并发地执行
- 持久性(durability):一个事务完成后,它对数据库的改变必须是永久的,即使系统出现故障.
事务并发产生的问题
- 更新丢失:当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题——最后的更新覆盖了其他事务所做的更新。
举例:
事务1:更改了一行数据,未提交
事务2:更改了同一行数据,提交
事务1:提交 - 脏读:一个事务读取到了另一个事务没有提交的数据.
举例:
事务1:更新一条数据
事务2:读取事务1更新的这条数据
事务1:提交刚才更新的数据 - 不可重复度:在同一事务中,两次读取到的数据,得到的内容不同.
举例:
事务1:读取一条数据
事务2:修改事务1刚才读取的那条数据
事务1:再次读取这条数据,发现跟刚才读取的不一致 - 幻读:同一事务中,同样的操作执行两次,得到的记录数不同.
举例:
事务1:进行一次操作,这次操作修改涉及到表的所有行
事务2:向表中插入一条数据,提交
事务1:再次查询发现有一条数据没有修改到,就像是产生了幻觉了一样
事务的隔离性级别
- 未提交读:允许读取未提交数据.这是SQL允许的最低一致性级别.也就是允许出现以上三种提到的情况
- 已提交读:只允许读取已提交数据,但不要求可重复读.也就是脏读不可能出现,其他两种情况有可能出现.
- 可重复读:只允许读取已提交数据,而且在一个事务两次读取一个数据项期间,其他事务不得更新该数据.也就是脏读和不可重复读不可能出现,但有可能出现幻读.
- 可串行化:通常保证可串行化调度.也就是以上三种情况都不可能出现,是SQL中的最高一致性级别.
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
未提交读 | √ | √ | √ |
已提交读 | × | √ | √ |
可重复读 | × | × | √ |
可串行化 | × | × | × |
数据库中的锁机制
1.共享锁:如果事务T1获得了数据项Q上的共享锁,则T1可读但不可写Q.这时其他事务可读Q但不可写Q
2.排他锁:如果事务T1过的了数据项Q上的排他锁,则T1既刻度又可写Q.这时其他事务既不可读Q也不可写Q.
- 锁的相容性:如果T1请求对数据项加A类锁,而事务T2当前在数据项Q上拥有B类锁,尽管如此,但是事务T1可以立即获得数据项Q上的锁,则我们称A类锁和B类锁是相容的.
数据库设计
数据库设计的三个范式
第一范式(1NF):表的所有属性的都是原子的、不可再分的。比如地址可以分解成城市、区域、街道等,这就不符合第一范式。
第二范式(2NF):在第一范式的基础上,消除了非主属性对码的部分函数依赖,也就是不能仅仅依赖于码中的部分主码,必须依赖于码的全部主码。
第三范式(3NF):在第二范式的基础上,消除了非主属性对码的传递函数依赖,通俗地讲就是非主属性之间没有相互依赖。
BC范式:在第三范式的基础上,消除了主属性对码的部分和传递函数依赖,即任意属性对码的传递函数依赖。