日期:2014-05-16  浏览次数:20627 次

JDBC 事物的隔离级别

在分布式的系统中,通常会有多个线程连接到数据库中同时对一个表进行操作(这里的同时并不表示同一个时间点,而是同时竞争cpu的资源,至于如何调度,就要看线程和操作系统如何进行调度了),这种情况下如果会话的事物设置不当,就会导致数据混乱,常常会出现以下三种情况(假设现在系统中有两个会话A和B,同时对表T_Test操作):


1.脏读:假如A开启事物后,在查询之前,B修改了表中的某条记录,但是事物还没提交,这个时候A再读取该表时,读到了B修改之后的数据,问题发生了:B如果此时回滚了事物,那么A读到的就是错误的数据了。
2.不可重复读:假如A开启事物后,对表做了查询后,此时B修改了表中的某条记录,然后A又做了一次查询,问题发生了:对于事物A,第一次读取的结果对应的记录和第二次读取的结果不一致了
3.幻读:假如A开启事物后,对表做了查询,此时B在表中新增了一条数据,然后A又做了一次查询,问题发生了:对于事物A,第二次读取的结果比第一次读取的结果多出一条记录

?

因此,在JDBC的规范中对事物隔离级别做了相应的规定。
1.读未提交(Read Uncommitted):这种隔离级别可以让当前事务读取到其它事物还没有提交的数据。这种读取应该是在回滚段中完成的。通过上面的分析,这种隔离级别是最低的,会导致引发脏读,不可重复读,和幻读。


2.读已提交(Read Committed):这种隔离级别可以让当前事务读取到其它事物已经提交的数据。通过上面的分析,这种隔离级别会导致引发不可重复读,和幻读。


3.可重复读取(Repeatable Read):这种隔离级别可以保证在一个事物中多次读取特定记录的时候都是一样的。通过上面的分析,这种隔离级别会导致引发幻读。


4.串行(Serializable):这种隔离级别将事物放在一个队列中,每个事物开始之后,别的事物被挂起。同一个时间点只能有一个事物能操作数据库对象。这种隔离级别对于数据的完整性是最高的,但是同时大大降低了系统的可并发性。