锁模块之数据库事务的四大特性
数据库事务的四大特性和程序事务的四大特性基本相同
⑴ 原子性(Atomicity)
原子性,这个是最简单的。说的是一个事务内所有操作共同组成一个原子包,要么全部成功,要么全部失败。这是最基本的特性,保证了因为一些其他因素导致数据库异常,或者宕机。
⑵ 一致性(Consistency):一致状态的转变,应该满足完整性约束。
一致性,这个是大家误解最深的,很多博客都喜欢用银行转账的例子来讲一致性,所谓的一致性是基于原子性。
原子性只保证了一个事务内的所有操作同一性,大家同生死,不会出现你死了,我还活着。但是,原子性并没有保证大家同一时刻一起生,一起死。计算机指令是有先后顺序的,这样就决定了一个事务的提交,会经历一个时间过程,那么如果事物提交进行到了一半,我读取了数据库,会不会读到中间结果? **为了防止这样的情况,数据库事务的一致性就规定了事物提交前后,永远只可能存在事务提交前的状态和事务提交后的状态,**从一个一致性的状态到另一个一致性状态,而不可能出现中间的过程态。也就是说事务的执行结果是量子化状态,而不是线性状态。数据库提交事务会有一个过程,如果提交的时候,存在一个时间差,在提交的第一秒,一个删除过程还没完成到了第三秒才完成,会不会第一秒访问的人和第三秒访问的人得到不同的结果?出现不一致,状态的混沌?这就是一致性得保证的只会有前状态和后状态,绝不会出现中间态。
⑶ 隔离性(Isolation)–锁方案隔离
事务的隔离性,基于原子性和一致性,因为事务是原子化,量子化的,所以,事务可以有多个原子包的形式并发执行,但是,每个事务互不干扰。但是,由于多个事务可能操作同一个资源,不同的事务为了保证隔离性,会有很多锁方案,当然这是数据库的实现,他们怎么实现的,我们不必深究。
⑷ 持久性(Durability)–DBMS的恢复性能
持久性,当一个事务提交之后,数据库状态永远的发生了改变,这个事务只要提交了,哪怕提交后宕机,他也确确实实的提交了,不会出现因为刚刚宕机了而让提交不生效,是要事务提交,他就像洗不掉的纹身,永远的固化了,除非你毁了硬盘。
锁模块之事务并发访问产生的问题以及事务隔离机制
SELECT @@tx_isolation;
设置事务隔离级别
SELECT @@tx_isolation;
set SESSION TRANSACTION ISOLATION level read UNCOMMITTED;
SELECT @@tx_isolation;
开启事务
begin transaction
数据脏读的产生:Read UNCOMMITTED 隔离级别下,两个事务同时对同一行进行修改,一旦其中有一个事务发生了Roll Back(回滚)操作,就会造成另一个事务产生脏读,读了脏数据,Dirty Read.
避免脏读,设置更加严格的事务隔离级别,比如设置为 Read committed
SELECT @@tx_isolation;
set SESSION TRANSACTION ISOLATION level read COMMITTED;
SELECT @@tx_isolation;
读提交 是Oracle 默认的事务隔离级别 Read committed
Read UNCOMMITTED (会有脏读)–》Read committed (避免脏读)–》REPEATABLE-READ
不可重复读的产生:Read COMMITTED 隔离级别下,同一个事务对同一行进行多次查询,因为别的事务发生对该同一行进行了更新操作,就会产生在同一个事务的前后查询出来的数据前后不一致的情况出现,如果这个事务继续修改数据,就会产生数据混乱的恶果出现。
解决不可重复读:设置成InnoDB的事务默认隔离级别,REPEATABLE READ;
SELECT @@tx_isolation;
set SESSION TRANSACTION ISOLATION level REPEATABLE READ;
SELECT @@tx_isolation;
幻读是什么:幻读是说??
幻读是指当事务不是独立执行时发生的一种现象。
事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样.一般解决幻读的方法是增加范围锁RangeS,锁定检索范围为只读,这样就避免了幻读。
在数据库定义的四种隔离级别中
最高隔离级别SERIALIZABLE_READ可以保证不出现幻读的问题。
Repeatable Read (RR)
针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁),不存在幻读现象
如何解决幻读?
注意:Mysql 的 InnoDB 的可重复读事务隔离级别,通过巧妙的方式避免了幻读的发生。
总结:记得还要去了解Redo Log 等等
什么是当前读?
什么是快照度:MVCC,多版本
在 Read Commited 级别下,当前读和快照读
Undo Log日志
Undo Log日志