`
darkma
  • 浏览: 521795 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类

Spring @Transactional

阅读更多

J2EE开发者有两种事务管理选择,全局和本地事务。Spring框架对事务管理的支持极大地改变传统上认为J2EE应用需要应用服务器。这种改变不单是仅仅为了通过EJB来使用生命式事务而使用应用服务器。事实上,即使你的应用服务器有强大的JTA功能,Spring框架的声明式事务提供了比EJB CMT(声明式事务)更强大,更高效的编程模型。一般来说,只有支持多个事务资源,才会需要应用服务器的JTA功能,而大多数应用不需要能够处理跨多种资源。最重要的一点,使用Spring,你可以选择何时把你的应用迁移到全功能的应用服务器。使用Spring不需要像以前一样用编码实现本地事务代替EJB CMT或JTA,现在只需要改配置问价,而不必改代码。

 

一. Spring事务管理
1. Spring 编程式事务管理(programmatic transaction management)
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(def);
try {
 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
 jdbcTemplate.update("INSERT INTO USER VALUES('001', 'Jack', 'M', 29)");
 jdbcTemplate.update("INSERT INTO USER VALUES('007, 'James Bond', 'M', 35)");
} catch (DataAccessException ex) {
 transactionManager.rollback(status); // 也可以執行status.setRollbackOnly();
        throw ex;
}
transactionManager.commit(status);
见:http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2398

 

2. Spring宣告式事务管理(declarative transaction management)主要是在spring的配置文件中设置
<bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 <property name="transactionManager">
  <ref bean="transactionManager"/>
 </property>
 <property name="target">
  <ref bean="userDAO"/>
 </property>
 <property name="transactionAttributes">
 <props>
  <prop key="insert*">PROPAGATION_REQUIRED</prop>
 </props>
 </property>
</bean>
见:http://www.javaworld.com.tw/confluence/pages/viewpage.action?pageId=2402

 

二. Spring的@Transcation的例子
1. class 中
@Component //注释就可以将该类定义了 Spring 容器中的 Bean
public Class UserDaoImpl implements IUserDao {
 @Override
 // 标志updateUsers()为@Transactional注解
 @Transactional(
  propagation = Propagation.REQUIRED,
  isolation = Isolation.DEFAULT,
  rollbackFor = Exception.class
 )
 public void updateUsers(List<User> users){
  for(User user :users){
  //逻辑
  }
 }
}

注意:事务的属性和基本概念
Required : 如果在一个事务中调用,就将该方法加到此事务中,如果没有启动事务,就创建新事务
RequiredNew : 不管当前有没有事务,都启动新事务,如果有,会被挂起,直到此方法结束
NotSupported : 不能在事务中执行此方法,如果有事务,会被挂起,直到此方法结束 
Supports : 如果有当前事务,此方法回加到当前事务,如果没有,容器不会启动新事务
Mandatory : 必须在事务中执行此方法,否则会抛出异常 : TransactionRequiredException
Never : 必须不在事务中调用此方法,否则抛出RemoteException(远程调用)或EJBException(本地调用)

 

2.spring配置文件加入:

  .....................

 <!-- 配置Hibernate事物管理器 -->
 <bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
       <ref local="sessionFactory"/>
    </property>
   <property name="nestedTransactionAllowed" value="true"/>
 </bean>

  .....................

   .....................
  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
  http://www.directwebremoting.org/schema/spring-dwr    
         http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-2.5.xsd"
  default-autowire="byName" default-lazy-init="true">
 
 <!-- 启用 annotation 配置模式 -->
 <context:annotation-config />
 
 <!-- 扫描目标目录下的bean,完成自动注入 -->
 <context:component-scan base-package="com.cn.org.*" />
 <context:component-scan base-package="com.cn.user.*" />
 
 <!-- 启动 DWR 注解配置模式 -->
        <dwr:configuration />
        <dwr:annotation-config />
        <dwr:url-mapping />
        <!-- 开启dubug状态 -->
        <dwr:controller debug="true"/>
       
 <!-- 支持 @AspectJ 标记-->  
 <aop:aspectj-autoproxy proxy-target-class="true"/>  
     <!-- 使用 annotation 声明事务管理 -->
     <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
   </beans>
   .....................

 

注:webSerivces 是不支持事务的,如果使用事务,必须在下层的Object中实现,例如在Service层或者是Dao层实现。

 

另见:
http://www.ibm.com/developerworks/cn/java/j-ts1.html
http://www.javaworld.com.tw/confluence/display/opensrc/Spring
http://www.redsaga.com/spring_ref/2.0/html/transaction.html#transaction-declarative

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics