完整性约束概念
数据库完整性约束有很多,主要有以下几种:
- 实体完整性:规定表的每一行在表中是惟一的实体.
- 域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定.
- 参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散.
- 用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件.用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求.
比如:primary key(主键)约束,foreign key(外键)约束,not null,unique(惟一)约束,check约束
ACID
原子性(Atomicity):事务是数据库逻辑的单元,一个事务下包含的所有数据库操作,要么全部执行,要么全都不执行。若在事务执行过程中发生错误,会被回滚到事务开始前的状态,就跟这个事物从未执行过一样。
一致性(Consistency):事务前后,数据库的状态都满足完整性约束。
隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行导致的数据不一致。
持久性(Durability):事务处理结束后,对数据的修改是永久的。
脏读,不可重复读和幻读
脏读
当一个事务允许另一个事务读取其未提交的数据就可能发生脏读。
/ 事务 1 /SELECT age FROM users WHERE id = 1;/ will read 20 /
/ 事务 2 /UPDATE users SET age = 21 WHERE id = 1;/ No commit here /
/ 事务 1 /SELECT age FROM users WHERE id = 1;/ will read 21 /
/ 事务 2 /ROLLBACK; / lock-based DIRTY READ /
在这个例子中,如果age原先的值不是21,事务2回滚后,事务读到的数据就是脏数据了。
不可重复读
在一次事务中,当查询2次某一条记录,得到的结果不同就表示发生了“不可重复读”。在基于锁的并发控制中“不可重复读”现象发生在当执行SELECE 操作时没有获得读锁或者SELECT操作执行完后马上释放了读锁;多版本并发控制中当没有要求一个提交冲突的事务回滚也会发生“不可重复读”。
/ 事务 1 /SELECT * FROM users WHERE id = 1;
/ 事务 2 /UPDATE users SET age = 21 WHERE id = 1;COMMIT; / in multiversion concurrency control, or lock-based READ COMMITTED /
/ 事务 1 /SELECT FROM users WHERE id = 1;COMMIT; / lock-based REPEATABLE READ */
在这个例子中,事务2提交成功,因此他对id为1的行的修改就对其他事务可见了。但是事务1在此前已经从这行读到了另一个“age”的值。在可序列号和可重复度的隔离级别,数据库在第二次SELECT请求时应该返回事务2更新之前的值。在提交读和未提交读,返回的是更新之后的值,这个现象就是不可重复读。
幻读
事务执行过程中,当2个完全相同的查询语句得到2个不同的结果集,这种现象称为“幻读”(phantom read)。当事务获取范围锁的情况下,执行SELECT…WHERE语句就可能发生幻读。
区别:
“脏读”表示读到的数据实际上并不存在,是“脏”的,而“不可重复读”读到的数据原先是存在的,只不过发生了变化。
“幻读”和“不可重复读”的区别在于,前者侧重新增或删除,后者侧重修改。要想避免“幻读”需要锁住查询条件中相近的记录,而“不可重复读”只需要锁住查询条件中对应的记录。
事务隔离级别(隔离级别由低到高)
1.读未提交(READ-UNCOMMITTED)
最低的事务隔离级别,允许脏读。
2.读已提交(READ-COMMITTED)
不会出现脏读,但是不允许可重复读。
3.可重复读(REPEATABLE-READ)
允许重复读,读取相同的数据,不会出现事务A因为事务B的修改而导致的2次查询结果不一致。会出现幻读。
4.序列化(SERILIZABLE)
最高的隔离级别。在基于锁机制并发控制的DBMS实现可序列化,要求在选定对象的读锁和写锁保持到事务结束后才能释放。在SELECT的查询中使用一个”WHERE”子句来描述一个范围时应该获得的一个“范围锁”。这种机制可以避免“幻读”。
共享锁和排它锁
select … from table lock in share mode;
select … from table for update;
1 lock in share mode 是共享锁,简称S锁或者读锁
2 for update 是排他锁,简称X锁或者写锁
当事物1对读取的数据采用X锁或者S锁时,其他事务可以进行读操作,但是不允许修改,修改操作会阻塞。
S锁是共享的,相互之间不阻塞,当事务1对某一行数据加了S锁,事务2也对该行数据加S锁没有影响。
X锁是排它的,跟其它X锁和S锁之间不能同时使用,当事务1对某一行数据加了X锁时,事务2对该行数据加不了X锁或S锁了。