事务隔离级别指定哪些数据对事务中的语句可视。通过定义对同一目标数据源执行的事务之间的可能交互作用,这些级别直接影响并行访问级别。
数据库反常
数据库反常是生成的结果,这些结果从单一事务的作用域中看上去是不正确的,但从所有事务的作用域中看上去却是正确的。下面描述了不同类型的数据库反常:
- 在以下情况下,发生脏读取:
- 事务 A 将行插入到表中。
- 事务 B 读取这个新行。
- 事务 A 回滚。
事务 B 可能已根据事务 A 插入的行对系统执行了工作,但该行永远不会成为数据库的永久部分。
- 在以下情况下,发生不可重复读取:
- 事务 A 读取行。
- 事务 B 更改该行。
- 事务 A 再次读取同一行并获取新结果。
- 在以下情况下,发生幻象读取:
- 事务 A 读取所有满足 SQL 查询上的 WHERE 子句的行。
- 事务 B 插入附加的满足 WHERE 子句的行。
- 事务 A 对 WHERE 条件进行重新求值并获得附加的行。
注意:由于 DB2/400 具有锁定策略,所以它不会总是使应用程序暴露在规定级别的可允许数据库反常之下。
JDBC 事务隔离级别
在 IBM Developer Kit for Java JDBC API 中共有五个级别的事务隔离。它们按照限制性从低到高的次序列示如下:
-
JDBC_TRANSACTION_NONE
- 这是一个特殊的常量,指示 JDBC 驱动程序不支持事务。
-
JDBC_TRANSACTION_READ_UNCOMMITTED
- 此级别允许事务查看对数据所作的未提交更改。在此级别,所有数据库反常都是有可能的。
-
JDBC_TRANSACTION_READ_COMMITTED
- 此级别表示在提交事务之前,在该事务中所作的任何更改在该事务之外都不可视。这杜绝了脏读取的可能性。
-
JDBC_TRANSACTION_REPEATABLE_READ
- 此级别表示保持将读取的行锁定,从而使另一事务在此事务完成之前不能更改这些行。这将禁止脏读取和不可重复读取。幻象读取仍是有可能的。
-
JDBC_TRANSACTION_SERIALIZABLE
- 在事务期间将表锁定,从而使其它对表添加值或除去值的事务不能更改 WHERE 条件。这将杜绝所有类型的数据库反常。
可使用 setTransactionIsolation 方法来更改连接的事务隔离级别。
注意事项
有一种常见的误解,即认为 JDBC 规范定义了前面提到的五个事务级别。通常认为 TRANSACTION_NONE 值表示在不存在提交控制的情况下运行这一概念。然而,JDBC 规范并没有以同一方式定义 TRANSACTION_NONE。在 JDBC 规范中,将 TRANSACTION_NONE 定义成这样的一个级别:在这个级别,驱动程序不支持事务并且不是与 JDBC 相符的驱动程序。在调用 getTransactionIsolation 方法时,从来不会报告 NONE 级别。
由于 JDBC 驱动程序的缺省事务隔离级别是由实现定义的,所以问题稍微有点复杂。本机 JDBC 驱动程序缺省事务隔离级别的缺省事务隔离级别是 NONE。这允许驱动程序使用没有日志的文件,并且您不需要作任何指定(如指定 QGPL 库中的文件)。
本机 JDBC 驱动程序允许 将 JDBC_TRANSACTION_NONE 传送给 setTransactionIsolation 方法或指定 none 作为连接属性。然而,当值为 none 时,getTransactionIsolation 方法总是报告 JDBC_TRANSACTION_READ_UNCOMMITTED。跟踪正在运行的级别是应用程序的职责(如果应用程序有此需要的话)。
在过去的发行版中,由于系统没有真正自动提交方式这一概念,所以,如果对自动提交指定 true,则 JDBC 驱动程序将通过把事务隔离级别更改为 none 来进行处理。这在功能上极为相似,但并非在所有方案下都能提供正确的结果。现在情况已有所不同;数据库已将自动提交的概念与事务隔离级别的概念分开。因此,在启用自动提交的情况下在 JDBC_TRANSACTION_SERIALIZABLE 级别运行是完全有效的。唯一无效的方案是在 JDBC_TRANSACTION_NONE 级别运行并且不处于自动提交方式。当系统不是在具有事务隔离级别的情况下运行时,应用程序不能控制提交边界。
JDBC 规范与 iSeries 平台之间的事务隔离级别
iSeries 平台的事务隔离级别具有公共的名称,这些名称与 JDBC 规范提供的那些名称不匹配。下表对 iSeries 平台使用的那些与 JDBC 规范所使用的名称不匹配的名称作了匹配:
JDBC 级别 * | iSeries 级别 |
---|---|
JDBC_TRANSACTION_NONE | *NONE 或 *NC |
JDBC_TRANSACTION_READ_UNCOMMITTED | *CHG 或 *UR |
JDBC_TRANSACTION_READ_COMMITTED | *CS |
JDBC_TRANSACTION_REPEATABLE_READ | *ALL 或 *RS |
JDBC_TRANSACTION_SERIALIZABLE | *RR |
* 在这个表中,JDBC_TRANSACTION_NONE 值与 iSeries 级别 *NONE 和 *NC 排在一起是为了使您看得更清楚。这并不是直接的从规范到 iSeries 级别的匹配。