事务的级别控制

原创 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("程序执行结束!");
	}
}


理解事务的4种隔离级别

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。Read uncommitt...
  • qq_33290787
  • qq_33290787
  • 2016年07月16日 16:19
  • 53817

数据库事务隔离级别

本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read comm...
  • FG2006
  • FG2006
  • 2011年11月04日 22:51
  • 118395

mysql 事物级别

事务隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也会越大。MySQL事务包含如下4个隔离级 别,按隔离级别从低到高排列如下。 (1)read uncommitted(dirty...
  • weixin_40953585
  • weixin_40953585
  • 2018年01月16日 09:50
  • 19

事物的五种隔离级别

二、独占锁、共享锁、更新锁,乐观锁、悲观锁 1、锁的两种分类方式 (1)从数据库系统的角度来看,锁分为以下三种类型: 独占锁(Exclusive Lock) 独占锁锁定的资源只允...
  • u014033218
  • u014033218
  • 2017年07月28日 11:05
  • 196

java控制事务级别

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

MySQL并发控制——事务与事务隔离级别详解

一、首先了解什么是事务 1、事务概念:事务是包含了一组有序的数据库操作命令的序列,它是数据库并发操作的最小控制单位。 2、事务特性:原子性:事务包含的数据库操作命令要么都执行,要么都不执行。 一...
  • zhangliangzi
  • zhangliangzi
  • 2016年06月01日 11:54
  • 1804

事物及事物隔离级别

什么是事物 事物是访问数据库的一个操作序列,数据库应用系统通过事物集来完成对数据库的存取。事物的正确执行使得数据库从一种状态转换为另一种状态。 事物必须服从ISO/IEC所制定的ACI...
  • tianya3530
  • tianya3530
  • 2017年01月03日 11:42
  • 152

postgresql 事务级别

Postgresql是一个基于多版本并发控制实现的数据库.事务隔离级别标准的事务隔离级别包括: 1. 读未提交 2. 读已提交 3. 可重复读 4. 序列化在正式的postgresql...
  • scugxl
  • scugxl
  • 2016年04月12日 00:12
  • 2461

mysql事务级别设置

一.            全局设置 1.   全局修改,修改mysql.ini配置文件,在最后加上 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED,REPEATABL...
  • hittata
  • hittata
  • 2015年04月14日 10:02
  • 1970

真正理解mysql的事务级别

什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 ...
  • jjwen
  • jjwen
  • 2017年03月30日 17:41
  • 972
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:事务的级别控制
举报原因:
原因补充:

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