`
xinklabi
  • 浏览: 1586593 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
文章分类
社区版块
存档分类
最新评论

JDBC事物处理(Spring和Hibernate事物的底层实现,帮助你理解一些配置的参数的意义)

 
阅读更多
jdbc中的事务处理
2008-11-13 11:54

基本上,事务代表了工作的一个逻辑单位。因为数据库的主要责任是保存信息,它需要有某种方法让用户可以指出当前的程序状态应该保存。同样地,当事情出错时,需要有一种方法来指出数据库应该忽略当前的状态而回到前面保存的程序状态。在数据库技术中,这些功能被称为事务。为了完成这些任务,JDBC API 包括了两个方法作为 Connection 接口的一部分。若将 Connection 对象名称指定为 conn,通过调用 conn.commit()。可以保存程序状态;通过调用 conn.rollback(); 可以返回到以前保存的状态。如果数据库实际运行操作时有错误发生,这两个方法都会抛出 SQLExceptions,所以您需要在 try ... catch 块中包装它们。

了解更多

据个例子吧。在单用户系统,事务非常容易理解 — 它们只是和保存或忘记应用程序的状态有关。然而,在多用户系统中,事务变得复杂多了。多用户事务的经典案例是银行帐户,其中一个应用程序试图在借记帐户,同时另一个应用程序试图贷记同一个帐户。如果您熟悉多线程编程,您以前可能见过这种问题。根本的问题是除非两个事务相互隔离,否则一个应用程序就可能影响另一个,从而导致错误的程序状态。在我们简单的案例中,这可能意味着一个帐户中有错误的金额,这将导致致命的错误。

当处理多个访问相同数据的用户时,通常可能出现三种问题:

  • 脏读。当应用程序使用了被另一个应用程序修改过的数据,而这个数据处于未提交状态时,就会发生脏读。第二个应用程序随后会请求回滚被其修改的数据。第一个事务使用的数据就会被损坏,或者“变脏”。
  • 单读。当一个事务获得了数据,而该数据随后被一个单独的事务所更改时,若第一个事务再次读取更改后的数据,就会发生单读。这样,第一个事务进行了一个单读。
  • 虚读。当事务通过某种查询获取了数据,另一个事务修改了部分该数据,原来的事务第二次获取该数据时,就会发生虚读。第一个事务现在会有不同的结果集,它可能包含虚读。

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

  • TRANSACTION_NONE 说明不支持事务。
  • TRANSACTION_READ_UNCOMMITTED 说明在提交前一个事务可以看到另一个事务的变化。这样脏读、单读和虚读都是允许的。
  • TRANSACTION_READ_COMMITTED 说明读取未提交的数据是不允许的。这个级别仍然允许单读和虚读产生。
  • TRANSACTION_REPEATABLE_READ 说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
  • TRANSACTION_SERIALIZABLE 是最高的事务级别,它防止脏读、单读和虚读。

     

     

 

 

 

 

您可能想知道,为什么不是所有事务都运行在 TRANSACTION_SERIALIZABLE 模式以保证最高程度的数据完整性呢?和处理多线程编程有关的问题相似,事务保护的级别越高,性能损失就越大。

假定您的数据库和 JDBC 驱动程序支持这个特性,则给定一个 Connection 对象,您可以明确地设置想要的事务级别:

conn.setTransactionLevel(TRANSACTION_SERIALIZABLE) ;

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

if(conn.getTransactionLevel() == TRANSACTION_SERIALIZABLE) {
System.out.println("Highest Transaction Level in operation.") ;
}
事务和批处理

缺省情况下,JDBC 驱动程序运行在被称为自动提交(AutoCommit)的模式下在这个模式下,发送到数据库的所有命令运行在它们自己的事务中。虽然这用起来很方便,但它带来了性能损失,因为事务需要一定数量的开销来作适当地设置。如果您想能够明确地控制提交和回滚,就需要用下面的语句禁用自动提交模式(我们仍然认为你声明的Connection对象为conn):

conn.setAutoCommit(false);

你也可以确认当前是否是自动提交模式:

if(conn.getAutoCommit() == true){
System.out.println("Auto Commit Mode");
}else{
System.out.println("Not Auto Commit Mode");
}

很多数据库支持批处理操作,在批处理操作中通过在一次单独的操作(或批处理)中执行多个数据库更新操作,开销可被最小化。批处理操作在 JDBC 2.0 中被引入,它要求事务不处于自动提交模式。我们还是来看代码:

conn.setAutoCommit(false) ;
Statement stmt = conn.createStatement() ;
stmt.addBatch("INSERT INTO people S('jerrykey', 123, 123, 123)") ;
stmt.addBatch("INSERT INTO people S('Kaede', 123, 123, 123)") ;
stmt.addBatch("INSERT INTO people S('kissjava', 123, 123, 123)") ;
int[] updateCounts = stmt.executeBatch() ;
con.commit() ;


注意,executeBatch() 方法返回一个更新计数的数组,每个值对应于批处理操作的一个命令。关于批处理操作的最后一个问题是,它们可能抛出一个类型为 BatchUpdateException 的新的异常,这个异常说明批处理操作中至少有一条命令失败了。这样,您就需要在try...catch...块中包含他们。

使用存储点进行严密的事务控制

从 JDBC 3.0 API 开始,增加了一个与事务相关的新的接口元素。这个接口引入了储存点的概念。储存点在数据库应用程序中提供了专门的标记,当调用回滚方法的时候它可以作为参数使用。因此,使用 JDBC 3.0 API 的话,现在就可能在开始复杂的数据库交互之前设置储存点,并根据结果提交整个事务,或者回滚到储存点,将应用程序返回到一个已知的状态。

要设置存储点,请参考一下代码:

Savepoint savePoint = conn.setSavepoint("savepoint");

这样你就创建了一个名字为savepoint的存储点。要回滚到一个给定的存储点,只需将想要的 Savepoint 对象作为参数传送到回滚方法即可。例如,我们想回滚到savepoint存储点:

conn.rollback(savePoint);

而你不想再用存储点的时候,可以释放他们:

conn.releaseSavepoint(savePoint);

注意,当您提交或回滚一个事务时,根据确切的顺序和操作的类型,任何已创建的存储点都可能变成无效的。请参考 JDBC 3.0 API 规范或您的驱动程序手册以了解更多信息。

来自:
http://hi.baidu.com/victorlin23/blog/item/6be754f2d508b314b07ec5a1.html

分享到:
评论

相关推荐

    hibernate源码分析一[启动过程]

    总的来说,Hibernate的启动过程涉及多个核心类和接口的协作,从配置文件的读取解析到`SessionFactory`的创建,每一步都至关重要,深刻理解这一流程对于掌握Hibernate框架的应用和优化具有重要意义。

    火炬博客系统7

    JDBC datasources及其它相关的资源,进行完整的事务管理和异常的包装,在此用了Spring的事物模板(TransactionTemplate)实现,可分离数据访问和事物处理,提高业务对象的可复用性,采用getHibernateTemplate()方法...

    火炬博客系统6

    JDBC datasources及其它相关的资源,进行完整的事务管理和异常的包装,在此用了Spring的事物模板(TransactionTemplate)实现,可分离数据访问和事物处理,提高业务对象的可复用性,采用getHibernateTemplate()方法...

    火炬博客系统5

    JDBC datasources及其它相关的资源,进行完整的事务管理和异常的包装,在此用了Spring的事物模板(TransactionTemplate)实现,可分离数据访问和事物处理,提高业务对象的可复用性,采用getHibernateTemplate()方法...

    java面试题

    Struts2以核心控制器FilterDispatcher为基础,包含了框架内部的控制流程和处理机制。 Hibernate工作原理,Hibernate数据持久化? 答:Hibernate工作原理: 1:读取并解析映射信息,创建SessionFactory 2:打开...

    Java软件工程师简历.pdf

    1. **网络运营支撑系统**:参与开发了基于Tomcat的J2EE系统,使用Struts、Hibernate和Spring技术,与Oracle 9i数据库配合,实现了用户管理、管理员管理等功能。系统通过Socket与Unix服务器通讯,实现信息同步。 2. ...

    java面试必备

    7. **异常处理**:理解异常的分类,何时抛出异常,如何进行有效捕获和处理,以及自定义异常的使用。 8. **设计模式**:工厂模式、单例模式、装饰器模式、代理模式等23种设计模式,理解它们的应用场景和优缺点。 9....

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    面试题包含了不同技术层面的面试问题,同时也能对一些没有面试开发经验的小白给予不可估量的包装, 让你的薪水绝对翻倍, 本人亲试有效.Java面试题84集、java面试专属及面试必问课程,所有的面试题有视屏讲解, 解答方案....

    java面试题集

    虽然这部分与Java面试题集不直接相关,但它可能包括C++的基础知识,如指针、内存管理等,对于理解某些底层机制可能有所帮助。 ### 十、Weblogic及其它 这部分可能涉及特定于Weblogic应用服务器的知识点,以及其他...

    值得收藏的2017年Java开发岗位面试题

    8. spring如何实现事物管理的。 Spring提供了多种事务管理机制,例如使用@Transactional注解或使用PlatformTransactionManager接口。 9. springIOC。 Spring IOC是Spring框架的核心组件,提供了依赖注入和控制反转...

Global site tag (gtag.js) - Google Analytics