声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 陈玮 JDBC1、事务的隔离性产生的问题:1.脏读(dirty read) 一个事务读取了另一个事务尚未提交的数据,当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下 update account set money=money+100 where name=’B’(此时A通知B) update account set money=money - 100 where name=’A’ 当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。 2.不可重复读(non-repeatable read)当一个事务多次读取时,发现数据有变化不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了 例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。 不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。 3.幻读(phantom read) 一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。 幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。 2、事务隔离模式,MYSQL默认的事务隔离级别,repeatable-read,可以防止脏读和不可重复读查看数据库当前的隔离级别:select @@tx_isolation;修改数据库事务隔离模式为(可以读取未提交的内容):这种模式会导致脏读情况发生,避免这种问题可以修改隔离模式为read-committed只读取提交后的数据; Set session tx_isolation=’read-uncommitted’; 设置为read-committed模式,依然会导致不可重复读的问题发生 上图例中可以看出,当A连接提交修改的数据后,导致B连接前后两次查询出的数据不一致。避免这种不可重复读的情况发生,可以将隔离模式设置为repeatable-read(可重复读模式) 上图例,将隔离模式设置为可重复读,当A连接修改数据时,对B连接的查询结果没有影响,当A连接提交事务后,对B连接的查询结果也没有影响,只有当B连接也提交事务后,才会查询出最新的数据。但是此种模式依然会导致幻读的发生。 防止幻读的发生可设置为Serializable可串化模式。 总结:Read Uncommitted(读取未提交内容) 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。 Read Committed(读取提交内容) 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。 Repeatable Read(可重读) 这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。 Serializable(可串行化) 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。 |