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

JSP 事务的操作

<%@ page language="java" contentType="text/html; charset=gbk"
    pageEncoding="gbk"%>
<%@ page import="java.sql.*,java.util.*,java.sql.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>JSP 事务的操作</title>
</head>
<body>
<%
	Connection conn=null;
	Statement stmt=null;
	ResultSet rs=null;
	java.util.Date date=new java.util.Date();
	out.println(date.getTime());
	out.println("<br/>");
	try{
		conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","zhang","zhang");
		conn.setAutoCommit(false);////禁止自动提交,设置回滚点
		stmt=conn.createStatement();
		String sql="select * from ins order by createtime desc";
		stmt.execute(sql);
		String sqll="update ins set mobile='80080008888' where id>322";
		stmt.executeUpdate(sqll);//数据库更新操作
		conn.commit();
		rs=stmt.executeQuery(sql);
		while(rs.next()){
			out.println(rs.getInt("id")+":");
			out.println(rs.getString("createtime")+":");
			out.println(rs.getString("username")+":");
			out.println(rs.getString("mobile")+":");
			out.println("<br/>");
			
		}
		
	}catch(Exception e){
		e.printStackTrace();
		try{
			conn.rollback(); //操作不成功则回滚
		}catch(Exception e1){
			e1.printStackTrace();
		}
	}


 %>


</body>
</html>



上面是我写的,下面是摘来的

1. 概述:



在jdbc的数据库操作中,一项事务是由一条或是多条表达式所组成的一个不可分割的工作单元。我们通过提交commit()或是回滚rollback()来结束事务的操作。关于事务操作的方法都位于接口java.sql.Connection中。



2. 特点:

★ 在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。

★ 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用 rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性,示例如下:
try {
conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","userpwd";
conn.setAutoCommit(false);//禁止自动提交,设置回滚点
stmt = conn.createStatement();
stmt.executeUpdate(“alter table …”); //数据库更新操作1
stmt.executeUpdate(“insert into table …”); //数据库更新操作2
conn.commit(); //事务提交
}catch(Exception ex) { 
ex.printStackTrace();
try {
conn.rollback(); //操作不成功则回滚
}catch(Exception e) {
e.printStackTrace();
}
}


JDBC事物及其加锁:

5种支持:

static int TRANSACTION_NONE = 0;
→禁止事务操作和加锁。

static int TRANSACTION_READ_UNCOMMITTED = 1;
→允许脏数据读写(dirty reads)、重复读写(repeatable reads)和影象读写(phntom reads)


static int TRANSACTION_READ_COMMITTED = 2;
→禁止脏数据读写(dirty reads),允许重复读写(repeatable reads)和影象读写(phntom reads)



static int TRANSACTION_REPEATABLE_READ = 4;
→禁止脏数据读写(dirty reads)和重复读写(repeatable reads),允许影象读写(phntom reads)



static int TRANSACTION_SERIALIZABLE = 8;
→禁止脏数据读写(dirty reads)、重复读写(repeatable reads)和允许影象读写(phntom reads)



2种密度:



最后一项为表加锁,其余3~4项为行加锁。



(注:
脏数据读写(dirty reads):当一个事务修改了某一数据行的值而未提交时,另一事务读取了此行值。倘若前一事务发生了回滚,则后一事务将得到一个无效的值(脏数据)。
重复读写(repeatable reads):当一个事务在读取某一数据行时,另一事务同时在修改此数据行。则前一事务在重复读取此行时将得到一个不一致的值。
影象读写(phantomreads):当一个事务在某一表中进行数据查询时,另一事务恰好插入了满足了查询条件的数据行。则前一事务在重复读取满足条件的值时,将得到一个额外的“影象“值。)



Jdbc根据数据库提供的缺省值来设置事务支持及其加锁,当然,也可以手工设置:
setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);

可以查看数据库的当前设置:
getTransactionIsolation()

需要注意的是,在进行受动设置时,数据库及其驱动程序必须得支持相应的事务操作操作才行。

上述设置随着值的增加,其事务的独立性增加,更能有效的防止事务操作之间的冲突;同时也增加了加锁的开销,降低了用户之间访问数据库的并发性,程序的运行效率也回随之降低。因此得平衡程序运行效率和数据一致性之间的冲突。一般来说,对于只涉及到数据库的查询操作时,可以采用 TRANSACTION_READ_UNCOMMITTED方式;对于数据查询远多于更新的操作,可以采用 TRANSACTION_READ_COMMITTED方式;对于更新操作较多的,可以采用TRANSACTION_REPEATABLE_READ;在数据一致性要求更高的场合再考虑最后一项,由于涉及到表加锁,因此会对程序运行效率产生较大的影响。