两个并发事务同时访问数据库表相同的行时,可能存在以下三个问题:
1、幻想读:事务T1读取一条指定where条件的语句,返回结果集。此时事务T2插入一行新记录,恰好满足T1的where条件。然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这条新纪录就是幻想。
2、不可重复读取:事务T1读取一行记录,紧接着事务T2修改了T1刚刚读取的记录,然后T1再次查询,发现与第一次读取的记录不同,这称为不可重复读。
3、脏读:事务T1更新了一行记录,还未提交所做的修改,这个T2读取了更新后的数据,然后T1执行回滚操作,取消刚才的修改,所以T2所读取的行就无效,也就是脏数据。
一、为了处理这些问题,SQL标准定义了以下几种事务隔离级别:
READ UNCOMMITTED 幻想读、不可重复读和脏读都允许。一个会话可以读取其他事务未提交的更新结果,如果这个事务最后以回滚结束,这时的读取结果就可能是不正确的,所以多数的数据库都不会运用这种隔离级别。
READ COMMITTED 允许幻想读、不可重复读,不允许脏读。一个会话只能读取其他事务已提交的更新结果,否则,发生等待,但是其他会话可以修改这个事务中被读取的记录,而不必等待事务结束,显然,在这种隔离级别下,一个事务中的两个相同的读取操作,其结果可能不同。
REPEATABLE READ 允许幻想读,不允许不可重复读和脏读。在一个事务中,如果在两次相同条件的读取操作之间没有添加记录的操作,也没有其他更新操作导致在这个查询条件下记录数增多,则两次读取结果相同。换句话说,就是在一个事务中第一次读取的记录保证不会在这个事务期间发生改动。SQL Server是通过在整个事务期间给读取的记录加锁实现这种隔离级别的,这样,在这个事务结束前,其他会话不能修改事务中读取的记录,而只能等待事务结束,但是SQL Server不会阻碍其他会话向表中添加记录,也不阻碍其他会话修改其他记录。
SERIALIZABLE 幻想读、不可重复读和脏读都不允许。在一个事务中,读取操作的结果是在这个事务开始之前其他事务就已经提交的记录,SQL Server通过在整个事务期间给表加锁实现这种隔离级别。在这种隔离级别下,对这个表的所有DML操作都是不允许的,即要等待事务结束,这样就保证了在一个事务中的两次读取操作的结果肯定是相同的。SQL标准所定义的默认事务隔离级别是SERIALIZABLE。
二、Oracle中的隔离级别及实现机制:
Oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。所以Oracle不支持脏读,即Oracle中不允许一个会话读取其他事务未提交的数据修改结果,从而防止了由于事务回滚发生的读取不正确。
Oracle回滚段,在修改数据记录时,会把这些记录被修改之前的结果存入回滚段或撤销段中。Oracle读取操作不会阻碍更新操作,更新操作也不会阻碍读取操作,这样在Oracle中的各种隔离级别下,读取操作都不会等待更新事务结束,更新操作也不会因为另一个事务中的读取操作而发生等待,这也是Oracle事务处理的一个优势所在。
Oracle缺省的配置是Read Committed隔离级别(也称为语句级别的隔离),在这种隔离级别下,如果一个事务正在对某个表执行 DML操作,而这时另外一个会话对这个表的记录执行读取操作,则Oracle会去读取回滚段或撤销段中存放的更新之前的记录,而不会象SQL Server一样等待更新事务的结束。
Oracle的Serializable隔离级别(也称为事务级别的隔离),事务中的读取操作只能读取这个事务开始之前已经提交的数据结果。如果在读取时,其他事务正在对记录执行修改,则Oracle就会在回滚段或撤销段中去寻找对应的原来未经修改的记录(而且是在读取操作所在的事务开始之前存放于回滚段或撤销段的记录),这时读取操作也不会因为相应记录被更新而等待。
设置隔离级别使用 SET TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
下面是oracle 设置SERIALIZABLE隔离级别一个示例:
左面是事务T1,右面是事务T2,因为T2级别为SERIALIZABLE,所以即使事务T1在提交了数据之后,事务T2还是看不到T1提交的数据,幻想读和不可重复读都不允许了。
那如何能查看到T1新增的记录呢? 上面T1和T2是并发执行,在T1执行insert的时候事务T2已经开始了,因为T2级别是SERIALIZABLE,所以T2所查询的数据集是T2事务开始前数据库的数据。即事务T1在事务T2开始之后的insert和update操作的影响都不会影响事务T2。现在重新开启一个事务T3 就可以看到T1新增的记录了。
当下列事件发生时,事务就开始了:
1、连接到数据库,并执行第一条DML语句
2、前一个事务结束后,又输入了另一条DML语句
相关推荐
介绍数据库事务的四种隔离级别,比较不同隔离级别的区别和影响
Oracle 数据库隔离级别是数据库事务处理中的核心概念,它决定了事务在并发环境下如何访问和处理数据,以确保数据的一致性和完整性。隔离级别主要解决的是并发操作中的脏读、不可重复读和幻读问题。 脏读(Dirty ...
数据库事务和隔离级别
### 数据库事务隔离级别详解 #### 一、引言 在多用户共享的数据库系统中,为了保证数据的一致性和准确性,必须对并发事务进行控制。数据库事务隔离级别是用来管理多个事务之间相互影响的程度,主要解决的问题包括脏...
Spring 框架提供了一套完善的事务管理机制,其中包含了多种事务传播属性和事务隔离级别。这些特性使得在处理数据库操作时,能够更好地控制事务的边界和行为,从而确保数据的一致性和完整性。 首先,我们来看一下...
数据库事务隔离级别和锁机制是确保数据库并发操作正确性和一致性的关键组成部分。在数据库系统中,尤其是大型企业级应用,多个用户可能同时访问和修改相同的数据,因此并发控制显得尤为重要。 事务的四个基本特征...
##### 3.3 Oracle 数据库中的并发事务隔离级别 在多用户环境中,多个事务可能会同时访问相同的数据。为了保证数据的一致性,Oracle 支持不同的隔离级别。这些隔离级别可以控制事务之间数据的可见性,从而减少或消除...
在SQL SERVER和ORACLE中,事务隔离级别是不同的,它们决定了并发操作时数据的可见性和一致性。SQL SERVER提供了四种隔离级别:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable ...
为了减少这些问题的影响,数据库管理系统提供了不同等级的隔离级别来控制事务间的交互。 #### 二、隔离级别的定义及影响 根据ANSI/ISO SQL92标准,隔离级别包括以下几种: 1. **未提交读(Read Uncommitted)**:...
数据库事务的四种隔离级别的特点描述,他们的使用热度,以及各种锁在隔离级别下的释放时机。
总而言之,Oracle数据库指南为用户提供了学习和掌握Oracle数据库技术的宝贵资源,文档中涉及的知识点不仅包括了数据库的基本操作和管理,还涵盖了高级功能如网格计算、数据处理的事务控制,以及对软件使用的法律约束...
- 实现事务管理:提交、回滚和设置事务隔离级别。 - 使用存储过程和函数:调用数据库中的自定义逻辑。 - 数据源管理:通过连接池提高应用性能和资源利用率。 在J2EE应用服务器中,通常会配置数据源,这样应用可以...
8. **优化技巧**:包括使用PreparedStatement避免SQL注入,合理设置批处理大小,使用连接池,以及使用合适的事务隔离级别等。 9. **Quartz Job与Oracle结合**:`quartz_job.xml`可能定义了Quartz作业,这些作业可能...
数据库事务隔离级别是数据库管理系统为确保并发环境下数据一致性而设定的一种机制。在多用户同时访问数据库的场景下,如果不加以控制,可能会出现各种数据安全问题,例如脏读、不可重复读和幻读。为此,数据库系统...
其核心特性包括ACID(原子性、一致性、隔离性和持久性)事务处理、多版本并发控制以及强大的备份和恢复机制。 二、Oracle数据库安装与配置 安装Oracle数据库涉及选择合适的软件版本、规划数据库实例、配置网络服务...
12. **数据库连接与工具**:介绍如何使用SQL*Plus、SQL Developer等工具连接Oracle数据库,以及ODBC和JDBC的使用。 `Ora9iSQLRef.chm`这个文件很可能是Oracle 9i版本的SQL参考指南,包含了9i版本中的SQL语法和特性...