事务的级别控制

原创 2012年03月23日 09:57:27

在SQL术语中,事务是逻辑工作单元(logical unit of work,LUW)构成的一个或多个语句。这在某种含义上意味着,一切都是事务。不过,通常而言,术语事务用来表示或全或无的系列操作;也就是说,要么一切十分成功,要么什么也没有发生。典型的事务是从银行帐户提款,并存放到另一个。只要提款完成,金额就消失了。另一个范例是复式薄记记帐法中的借方和贷方:借方和贷方都必须完成。

在单用户模式,事务非常容易理解-它们只是和保存或忘记应用程序的状态有关。在多用户模式中,事务变得复杂多了。多用户事务的经典说明是银行帐户,其中一个应用程序试图在借记帐户,同时另一个应用程序试图贷记同一个帐户。在前面已经介绍过多线程编程(并发编程)。类似的,事务的根本问题是保持两个事务相互隔离,否则一个应用程序就可能影响另一个,从而导致错误的程序状态。当处理多个访问相同数据的用户时,通常可能出现三种问题:

n 脏读:当应用程序使用了被另一个应用程序修改过的数据,而这个数据处于未提交状态时,就会发生脏读。第二个应用程序随后会请求回滚被其修改的数据。第一个事务使用的数据就会被损坏,或者"变脏"。

n 不可重复的读:当一个事务获得了数据,而该数据随后被一个单独的事务所更改时,若第一个事务再次读取更改后的数据,就会发生不可重复的读。这样,第一个事务进行了一个不可重复的读。

n 虚读:当事务通过某种查询获取了数据,另一个事务修改了部分该数据,原来的事务第二次获取该数据时,就会发生虚读。第一个事务现在会有不同的结果集,它可能包含虚读。

为了解决与"多个线程请求相同数据"相关的问题,事务之间用锁相互隔开。多数主流的数据库支持不同类型的锁;因此,JDBC API支持不同类型的事务,它们由Connection对象指派或确定。在JDBC API中可以获得下列事务级别:

n TRANSACTION_NONE 说明不支持事务

n TRANSACTION_READ_UNCOMMITTED说明在提交前一个事务可以看到另一个事务的变化。这样脏读,不可重复的读和虚读都是允许的。

n TRANSACTION_READ_COMMITTED说明读取未提交的数据是不允许的。这个级别仍然允许不可重复的读和虚读产生。

n TRANSACTION_REPEATABLE_READ说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。

n TRANSACTION_SERIALIZABLE是最高的事务级别,它防止脏读,不可重复读和虚读。

为什么不是所有事务都运行在TRANSACTION_SERIALIZABLE模式以保证最高程度的数据完整性呢?问题在于,和处理多线程编程有关的问题相似,事务保护的级别越高,性能损失就越大。假定您的数据库和JDBC驱动程序支持这个特性,则给定一个Connection对象,您可以明确地设置想要的事务级别:con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);

您还可以确定当前事务的级别:

int transactionIsolation = con.getTransactionIsolation();
if (transactionIsolation == Connection.TRANSACTION_NONE)
System.out.println("当前事务级别为:TRANSACTION_NONE。");

代码:

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.NamingException;

public class TranTest {
	public static void main(String[] args) {
		String jndiname = "jdbcPool/mydatasource";
		Connection con = null;
		try {
			con = DBCon.getConnectionFromPooledDataSource(jndiname);
			int transactionIsolation = con.getTransactionIsolation();
			if (transactionIsolation == Connection.TRANSACTION_NONE) {
				System.out.println("当前事务级别为:TRANSACTION_NONE。");
			} else if (transactionIsolation == Connection.TRANSACTION_READ_COMMITTED) {
				System.out.println("当前事务级别为:TRANSACTION_READ_COMMITTED。");
			} else if (transactionIsolation == Connection.TRANSACTION_READ_UNCOMMITTED) {
				System.out.println("当前事务级别为:TRANSACTION_READ_UNCOMMITTED。");
			} else if (transactionIsolation == Connection.TRANSACTION_REPEATABLE_READ) {
				System.out.println("当前事务级别为:TRANSACTION_REPEATABLE_READ。");
			} else if (transactionIsolation == Connection.TRANSACTION_SERIALIZABLE) {
				System.out.println("当前事务级别为:TRANSACTION_SERIALIZABLE。");
			}

			con.setAutoCommit(false);
			con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
			transactionIsolation = con.getTransactionIsolation();
			if (transactionIsolation == Connection.TRANSACTION_NONE) {
				System.out.println("当前事务级别为:TRANSACTION_NONE。");
			} else if (transactionIsolation == Connection.TRANSACTION_READ_COMMITTED) {
				System.out.println("当前事务级别为:TRANSACTION_READ_COMMITTED。");
			} else if (transactionIsolation == Connection.TRANSACTION_READ_UNCOMMITTED) {
				System.out.println("当前事务级别为:TRANSACTION_READ_UNCOMMITTED。");
			} else if (transactionIsolation == Connection.TRANSACTION_REPEATABLE_READ) {
				System.out.println("当前事务级别为:TRANSACTION_REPEATABLE_READ。");
			} else if (transactionIsolation == Connection.TRANSACTION_SERIALIZABLE) {
				System.out.println("当前事务级别为:TRANSACTION_SERIALIZABLE。");
			}

		} catch (NamingException ex) {
			System.err.println("Name Not Bound : " + ex.getMessage());
		} catch (SQLException ex) {
			System.err.println("SQLException : " + ex.getMessage());
		} finally {
			try {
				if (con != null)
					con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		System.out.println("程序执行结束!");
	}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

关于Mysql事务REPEATABLE_READ隔离级别下多版本并发控制(MVCC)重复读产生的坑的你踩过么?

前几天在系统中开发一个活动, 使用了行级锁,但是却在并发测试下出现了重大的Bug,话不多说, 直接开始. 事务的隔离级别是Mysql默认的REPEATABLE_READ. Time1: 事务A...

java控制事务级别

JDBC事务并发产生的问题和事务隔离级别原子操作使用事务,一组相关的操作。数据库是事务性的资源,在数据库中所有的操作都与事务相关。JDBC中自动提交是打开的,所以我们感觉不到事务。 1,如果con.s...

Informix的事务、并发控制、锁机制、隔离级别

Informix的事务、并发控制、锁机制、隔离级别

java中事务的隔离级别--依赖注入和控制反转

事务的隔离级别 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别;为了解决更新丢失,脏读,不可重读(包括虚读和幻读)等问题在标准SQL规范中,定义了4个事务隔离级别,分别为未授权读...

Informix的事务、并发控制、锁机制、隔离级别

Informix的事务、并发控制、锁机制、隔离级别

详解数据库中的事务、隔离级别、并发控制

一、什么是事务(Transaction)?  事务就是一组原子性的SQL查询,或者说一个独立的工作单元。下面我们通过一个银行用户之间的转账这个经典的例子来理解事务。 假设一个银行的数据库中有两张表...

事务四大隔离级别的不同

  • 2015-07-21 23:53
  • 51.86MB
  • 下载

数据库事务隔离级别

  • 2011-12-19 14:09
  • 154KB
  • 下载

事务并发控制、隔离级别及JDBC事务

1. DBMS事务并发控制     1.1 事务并发操作的问题         DMBS允许东西运行多个事务,这些事务可能同时操作同一数据对象。这可能造成以下问题  ...

Spring事务隔离级别.doc

  • 2015-09-18 13:56
  • 26KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)