Java事务开发常见问题
2011-09-19 16:25
337 查看
原文地址 http://ajava.org/course/java/8184.html
核心提示:一、了解事务源 我在面试中经常会问到这样的一个问题,假如有一个全局变量,在一个事务中修改了这个变量的值,而后这个事务因为别的原因回滚了,那这个变量的值会回滚到更改之前的值么? 其实事务只能对它所管理的资源进行提交和回滚,这些资源就是事务源,它
一、了解事务源
我在面试中经常会问到这样的一个问题,假如有一个全局变量,在一个事务中修改了这个变量的值,而后这个事务因为别的原因回滚了,那这个变量的值会回滚到更改之前的值么?
其实事务只能对它所管理的资源进行提交和回滚,这些资源就是事务源,它通常包括数据库连接资源,JMS队列资源等。事务的ACID(原子性,一致性,隔离性,持久性)属性也是针对它所管理的资源而言的。前面问题中的一个全局变量,可以说是内存中的一块存储空间,那么内存中的数据如何能具备事务属性中的持久性呢?很显然它不在事务的管辖范围之内,也就不会跟着事务的回滚而回滚了。
二、何时回滚事务
在JDBC事务和EJB的Bean管理事务中,我们通常会按下面这种方式控制事务的回滚。在出现某种的异常情况下,我们可以控制让事务回滚,当然也可以提交这个事务。
Connection cn = ...
cn.setAutoCommit(false);
Statement stmt = cn.createStatement();
try{
stmt.executeUpdate("update Order...");
cn.commit();
}catch(Exception e) {
cn.rollback(); //出现异常,回滚当前事务
}finally{
stmt.close();
cn.close();
}
但是对于EJB的容器管理事务或者Spring的声明式事务,就不大一样了。例如:
Connection cn = ...
cn.setAutoCommit(false);
Statement stmt = cn.createStatement();
try{
stmt.executeUpdate("update Order...");
cn.commit();
}catch(Exception e) {
cn.rollback(); //出现异常,回滚当前事务
}finally{
stmt.close();
cn.close();
}
我们只告诉EJB容器这个方法需要事务控制,容器会在方法的开始处启动一个事务,在方法返回之前提交这个事务。那如果中间处理过程中出现异常该怎么办? 默认情况下只有在RuntimeException和标注为ApplicationException的异常发成时会回滚事务,而在其他的情况下,事务都会提交。也就是说,在异常发生之前所有的操作都会被提交。这就有可能会出现部分提交的问题。有时为了确保一个方法所有的操作都被提交或者回滚,通常会这样做:
@TransactionAttribute(TransactionAttributeType.Required)
public void updateOrder(Order order) {
try{
...
}catch(Exception e) {
throw new EJBException(e);
}
}
在有异常发生时,捕获这个异常,并把它包装成一个EJBException,并重新抛出它。因为EJBException继承了RuntimeException,所以这里抛出一个EJBException告诉EJB容器回滚当前的事务。
另外需要注意的是另外一个方法:setRollbackOnly(),它与EJBException不同的是,它仅仅标记当前事务需要回滚,在方法执行完成之后容器会检查它并回滚事务,它并不抛出任何异常。
相比较EJB,Spring的声明式事务好像控制的更细致一些。来看下面的例子。
@Transactional(rollbackFor={Exception.class})
public void updateOrder(Order order) {
...
}
我们可以告诉Spring哪种类型的异常需要回滚,当然默认的还是只有在发生RuntimeException时事务会回滚。如果大家也在使用这种事务控制方式的话,还是主动告诉容器何时回滚,何时提交事务吧,采用默认值并不是一个好的办法。
核心提示:一、了解事务源 我在面试中经常会问到这样的一个问题,假如有一个全局变量,在一个事务中修改了这个变量的值,而后这个事务因为别的原因回滚了,那这个变量的值会回滚到更改之前的值么? 其实事务只能对它所管理的资源进行提交和回滚,这些资源就是事务源,它
一、了解事务源
我在面试中经常会问到这样的一个问题,假如有一个全局变量,在一个事务中修改了这个变量的值,而后这个事务因为别的原因回滚了,那这个变量的值会回滚到更改之前的值么?
其实事务只能对它所管理的资源进行提交和回滚,这些资源就是事务源,它通常包括数据库连接资源,JMS队列资源等。事务的ACID(原子性,一致性,隔离性,持久性)属性也是针对它所管理的资源而言的。前面问题中的一个全局变量,可以说是内存中的一块存储空间,那么内存中的数据如何能具备事务属性中的持久性呢?很显然它不在事务的管辖范围之内,也就不会跟着事务的回滚而回滚了。
二、何时回滚事务
在JDBC事务和EJB的Bean管理事务中,我们通常会按下面这种方式控制事务的回滚。在出现某种的异常情况下,我们可以控制让事务回滚,当然也可以提交这个事务。
Connection cn = ...
cn.setAutoCommit(false);
Statement stmt = cn.createStatement();
try{
stmt.executeUpdate("update Order...");
cn.commit();
}catch(Exception e) {
cn.rollback(); //出现异常,回滚当前事务
}finally{
stmt.close();
cn.close();
}
但是对于EJB的容器管理事务或者Spring的声明式事务,就不大一样了。例如:
Connection cn = ...
cn.setAutoCommit(false);
Statement stmt = cn.createStatement();
try{
stmt.executeUpdate("update Order...");
cn.commit();
}catch(Exception e) {
cn.rollback(); //出现异常,回滚当前事务
}finally{
stmt.close();
cn.close();
}
我们只告诉EJB容器这个方法需要事务控制,容器会在方法的开始处启动一个事务,在方法返回之前提交这个事务。那如果中间处理过程中出现异常该怎么办? 默认情况下只有在RuntimeException和标注为ApplicationException的异常发成时会回滚事务,而在其他的情况下,事务都会提交。也就是说,在异常发生之前所有的操作都会被提交。这就有可能会出现部分提交的问题。有时为了确保一个方法所有的操作都被提交或者回滚,通常会这样做:
@TransactionAttribute(TransactionAttributeType.Required)
public void updateOrder(Order order) {
try{
...
}catch(Exception e) {
throw new EJBException(e);
}
}
在有异常发生时,捕获这个异常,并把它包装成一个EJBException,并重新抛出它。因为EJBException继承了RuntimeException,所以这里抛出一个EJBException告诉EJB容器回滚当前的事务。
另外需要注意的是另外一个方法:setRollbackOnly(),它与EJBException不同的是,它仅仅标记当前事务需要回滚,在方法执行完成之后容器会检查它并回滚事务,它并不抛出任何异常。
相比较EJB,Spring的声明式事务好像控制的更细致一些。来看下面的例子。
@Transactional(rollbackFor={Exception.class})
public void updateOrder(Order order) {
...
}
我们可以告诉Spring哪种类型的异常需要回滚,当然默认的还是只有在发生RuntimeException时事务会回滚。如果大家也在使用这种事务控制方式的话,还是主动告诉容器何时回滚,何时提交事务吧,采用默认值并不是一个好的办法。
相关文章推荐
- Java事务开发常见问题
- Java 开发中常见的异常问题
- 日常 java web 开发中遇到的常见问题
- java开发eclipse常见问题(一)The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- 我的java学习之路-开发入门常见问题
- java开发工程师常见面试问题
- js传递二维数组到java后台 0人关注 讲义教程 资讯 常见问题 开发技巧
- java常用开发工具类大全,涵盖常见工作的问题(超赞)
- Java开发常见问题
- [jsp]常见问题--Java 开发中遇到的乱码问题
- java ssh开发常见问题总结
- Java开发环境配置及常见问题
- Java开发常见问题之 - java.lang.OutOfMemoryError:PermGen space
- Java Web开发工具配置 常见问题
- java web 开发中hibernate常见的基础问题
- java开发常见的一些问题总结
- android 开发之旅 R.java 常见问题
- JavaFast企业级快速开发平台-常见问题,入门必读
- java web开发中常见的乱码问题
- java开发常见问题 - java.lang.NoSuchMethodError:javax.persistence.Table.indexes()[Ljavax/persistence/Index;