`
thaIm
  • 浏览: 91561 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring --- Transaction Management

阅读更多
一)spring的事务管理
    事务管理并非spring独有,用过JDBC hibernate的朋友都知道,这些api和框架都提供了自己的事务管理机制。那么spring的事务管理又有些什么与众不同支持呢?它的优点又有哪些呢?总结来说大概有以下这么几点:
1' 为不同的事务API提供一致的编程模型,如Java Transaction API (JTA)、JDBC、Hibernate、JavaPersistenceAPI(JPA)以及JavaDataObjects(JDO)
2' 支持declarative transaction management(声明式事务管理)
3' 为一些原本比较复杂的事务API提供简化的programmatic transaction management(编程式事务管理)API
4' 出色的整合Spring数据访问抽象
    学习spring的事务管理的过程其实也就是通过例子理解以上4大优点的过程。所以下面,我们就结合实际的例子来慢慢分析这些优点吧 ^.^

二)整合Spring数据访问抽象
JDBC
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="${jdbc.driverClassName}" />
  <property name="url" value="${jdbc.url}" />
  <property name="username" value="${jdbc.username}" />
  <property name="password" value="${jdbc.password}" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

    它使用的是transaction manager类是:DataSourceTransactionManager。此外还定义了jdbc datasource。

JTA
    如果你datasource使用的是JNDI技术,并且通过JTA的API来进行事务管理,那么你的配置将会是这样:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/jpetstore"/>
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

    它对应的transaction mangager类是:JtaTransactionManager

Hibernate
    如果你使用过hibernate,你就知道hibernate中的sessionFactory对象是其核心控制类。它掌管着orm转换、连接配置、日志格式等众多属性配置。spring则在此基础上再做了一层封装以用于事务管理。所以配置样式如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="mappingResources">
    <list>
      <value>org/springframework/samples/petclinic/hibernate/petclinic.hbm.xml</value>
    </list>
  </property>
  <property name="hibernateProperties">
    <value>hibernate.dialect=${hibernate.dialect}</value>
  </property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>

    这里的datasource bean的配置和上面JDBC的例子中的一样,故这里就不再重复列出了。这里的transaction mangager类是HibernateTransactionManager

    总结来说:当我们使用JDBC时,我们调用的是DataSourceTransactionManager;当我们使用JTA时,我们调用的是JtaTransactionManager;而当我们使用Hibernate时,我们调用的是HibernateTransactionManager...其实,spring的事务管理,不论你最终采用哪种技术,它都是接口PlatformTransactionManager的一种实现。如果你进一步研究一下PlatformTransactionManager接口,你就会明白spring是如何将众多数据访问方法抽象统一的了:
public interface PlatformTransactionManager {
  TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
  void commit(TransactionStatus status) throws TransactionException;
  void rollback(TransactionStatus status) throws TransactionException;
}

    这里需要重点说明的是getTransaction(..)方法。它根据传入的TransactionDefinition类(它携带Isolation Propagation Timeout Read-only status等信息)来返回一个TransactionStatus类来代表新的一个事务或已存在的事务。有了这些接口,你完全可以自定义自己的transaction manager类。但还是那句话,绝大多数情况下,我们不需要这么做。spring已经为我们准备好了足够丰富的transaction manager类。

三)声明式事务管理
    依赖于spring AOP。我们举例说明,假设我们需要对接口FooService下所有类进行事务管理:
// the service interface that we want to make transactional
package x.y.service;
public interface FooService {
  Foo getFoo(String fooName);
  Foo getFoo(String fooName, String barName);
  void insertFoo(Foo foo);
  void updateFoo(Foo foo);
}

// an implementation of the above interface
package x.y.service;
public class DefaultFooService implements FooService {
  public Foo getFoo(String fooName) {
    throw new UnsupportedOperationException();
  }
  public Foo getFoo(String fooName, String barName) {
    throw new UnsupportedOperationException();
  }
  public void insertFoo(Foo foo) {
    throw new UnsupportedOperationException();
  }
  public void updateFoo(Foo foo) {
    throw new UnsupportedOperationException();
  }
}

    那么我们可以配置如下:
<!-- from the file 'context.xml' -->
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<!-- this is the service object that we want to make transactional -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>

<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
  <!-- the transactional semantics... -->
  <tx:attributes>
    <!-- all methods starting with 'get' are read-only -->
    <tx:method name="get*" read-only="true"/>
    <!-- other methods use the default transaction settings (see below) -->
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution of an operation defined by the FooService interface -->
<aop:config>
  <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
</aop:config>

<!-- don't forget the DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
  <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
  <property name="username" value="scott"/>
  <property name="password" value="tiger"/>
</bean>
<!-- similarly, don't forget the PlatformTransactionManager -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>
<!-- other <bean/> definitions here -->
</beans>

    对于回滚事务,我们可以指定:
<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
    <tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
    <tx:method name="*"/>
  </tx:attributes>
</tx:advice>

   上例显示的指出,对于NoProductInStockException,我们做回滚处理。此外<tx:method/>可以对propagation isolation做相应的设定。

四)编程式事务管理
    如果你要使用编程式的事务管理(适合少量需要事务管理的情形)。那么两个类可供你选择使用:TransactionTemplate 和 PlatformTransactionManager
1' TransactionTemplate
先是有返回值的情况:
public class SimpleService implements Service {
  // single TransactionTemplate shared amongst all methods in this instance
  private final TransactionTemplate transactionTemplate;
  // use constructor-injection to supply the PlatformTransactionManager
  public SimpleService(PlatformTransactionManager transactionManager) {
    Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
    this.transactionTemplate = new TransactionTemplate(transactionManager);
  }
  public Object someServiceMethod() {
    return transactionTemplate.execute(new TransactionCallback() {
    // the code in this method executes in a transactional context
    public Object doInTransaction(TransactionStatus status) {
      updateOperation1();
      return resultOfUpdateOperation2();
    }
    });
  }
}

无返回值的情况:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  protected void doInTransactionWithoutResult(TransactionStatus status) {
    try {
      updateOperation1();
      updateOperation2();
    } catch (SomeBusinessExeption ex) {
      status.setRollbackOnly();//代码显示的强行进行rollback
    }
  }
});

还可以进行一些属性的设置:
public class SimpleService implements Service {
  private final TransactionTemplate transactionTemplate;
  public SimpleService(PlatformTransactionManager transactionManager) {
    Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
    this.transactionTemplate = new TransactionTemplate(transactionManager);
    // the transaction settings can be set here explicitly if so desired
    this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
    this.transactionTemplate.setTimeout(30); // 30 seconds
    // and so forth...
  }
}


2' PlatformTransactionManager
有之前声明式事务管理的介绍,相信将PlatformTransactionManager转换为编程式的事务管理就简单了:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can only be done programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
  // execute your business logic here
}
catch (MyException ex) {
  txManager.rollback(status);
  throw ex;
}
txManager.commit(status);

  
五) propagation和isolation
1' propagation
  1、PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启。
  2、PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。
  3、PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
  4、PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务存在,则将这个存在的事务挂起。
  5、PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
  6、PROPAGATION_NEVER:总是非事务地执行,如果存在一个活动事务,则抛出异常。
  7、PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按TransactionDefinition.PROPAGATION_REQUIRED属性执行

2' isolation
  1、ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
  2、ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
  3、ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
  4、ISOLATION_REPEATALBE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻想读。它除了保证一个事务不能读取另外一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
  5、ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不课重复读外,还避免了幻想读。
分享到:
评论
1 楼 hvang1988 2016-07-08  

相关推荐

    spring-context-3.2.0 spring-core-3.2.0 等齐全的Spring jar包

    10. **spring-tx-3.2.0.RELEASE.jar**:事务管理模块提供了编程和声明式的事务管理,支持JTA(Java Transaction API)和本地事务。这使得在Spring应用中管理事务变得容易。 这组Spring 3.2.0库的完整集合,为开发者...

    struts2-spring-plugin-2.3.4.jar

    2. **事务管理(Transaction Management)**:Spring 提供了强大的事务管理功能,能够控制多个数据库操作是否作为一个事务进行。整合Struts 2 和Spring 后,我们可以在Spring 配置文件中定义事务规则,并让Spring ...

    mybatis-spring-1.3.3.jar官方下载

    5. **Transaction Management**:MyBatis-Spring 提供了与 Spring 事务管理的无缝集成,可以使用 Spring 的声明式事务管理来处理数据操作的事务。 在实际项目中,mybatis-spring-1.3.3.jar 包的使用步骤通常包括...

    spring-framework-5.0.4.RELEASEspring-framework-5.0.4.RELEASE

    Spring是什么呢?首先它是一个开源的项目,而且目前非常活跃...它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transaction Management

    Spring-JDBC,带一小例子

    2. **Transaction Management**: Spring-JDBC支持声明式事务管理,允许开发者使用注解(如@Transactional)来控制事务的边界,无需手动调用commit()和rollback()。这提高了代码的可读性和可维护性。 3. **...

    spring-jdbc-4.2.4.RELEASE.jar,spring-tx-4.2.4.RELEASE.jar,jdbcTemplate使用的jar包

    这个jar包是Spring的事务管理模块,提供了声明式事务管理(Declarative Transaction Management)和编程式事务管理(Programmatic Transaction Management)。声明式事务管理是Spring的一大特色,通过在XML配置或...

    spring-orm源码

    2. **Transaction Management** Spring提供了声明式事务管理,允许开发者在配置文件中定义事务边界,而无需在代码中显式处理。源码中,你可以看到TransactionProxyFactoryBean和PlatformTransactionManager是如何...

    完整Spring框架,包含源码文档等 spring-5.2.9.RELEASE-dist.zip

    springframework 是sping 里面的一个开源框架...它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transaction Management,等等......

    mybatis-spring-1.3.2.jar

    5. **Transaction Management**: MyBatis-Spring 与 Spring 的事务管理器集成,支持声明式事务管理。这意味着你可以利用 Spring 的事务注解(如 @Transactional)来控制事务边界,而无需在 DAO 层手动管理事务。 6....

    spring-framework-master.zip

    5. **事务管理(Transaction Management)**:Spring提供了一种统一的方式来管理事务,无论是编程式还是声明式,都能在不同的事务API之间无缝切换。 6. **Spring Boot**:Spring Boot简化了Spring应用的初始搭建...

    spring-mybatis-spring-2.0.2.zip

    2. **事务管理(Transaction Management)**:Spring提供了声明式事务管理,只需在配置文件中声明事务边界,无需在业务代码中手动控制事务的开启、提交和回滚。这种方式大大简化了事务处理,降低了出错的可能性。 3...

    mybatis-spring-1.3.1

    4. **Transaction Management**: MyBatis-Spring提供了Spring事务管理的支持,使得事务边界可以由Spring进行管理。这包括声明式事务和编程式事务,可以根据项目的具体需求选择适合的方式。 5. **ExecutorType**: 在...

    spring-framework-2.0-m1-with-dependencies.rar

    5. **Transaction Management**:事务管理功能进一步完善,支持声明式事务处理,通过注解或者XML配置即可完成事务管理。 三、依赖解析 在"spring-framework-2.0-m1-with-dependencies.rar"中,包含了Spring框架...

    spring-boot-reference.pdf

    51.3. Configuring Management-specific SSL 51.4. Customizing the Management Server Address 51.5. Disabling HTTP Endpoints 52. Monitoring and Management over JMX 52.1. Customizing MBean Names 52.2. ...

    spring-framework-4.3.6.RELEASE

    此外,它还提供了Transaction Management API,用于处理跨多个数据库操作的事务。 4. **Web MVC**: Spring的Model-View-Controller(MVC)框架是构建Web应用的首选,它提供了一种解耦的方式处理请求和响应。4.3.6...

    mybatis-spring-1.2.2

    5. **Transaction Management:** MyBatis-Spring 提供了基于 Spring 的事务管理。在 1.2.2 版本中,你可以利用 Spring 的声明式事务管理,只需在服务层的方法上添加 @Transactional 注解,就可以自动开启和提交...

    springspring-framework-3.0.0.M2

    6. **JMX(Java Management Extensions)集成**:Spring 3.0 提供了对 JMX 的全面支持,使应用程序的管理更加便捷,可以监控和管理应用的运行状态。 7. **Spring Expression Language (SpEL)**:Spring 3.0 引入的 ...

    spring-framework-reference 4.3.8.RELEASE

    Framework supports declarative transaction management, remote access to your logic through RMI or web services, and various options for persisting your data. It offers a full-featured MVC framework, ...

    spring-framework-4.1.9.RELEASE-dist

    4. **JMX改进**:增强了JMX(Java Management Extensions)的集成,便于管理和监控Spring应用。 5. **错误处理**:改进了错误和异常处理机制,使得问题定位更为方便。 三、Spring主要模块 1. **Core Container**:...

Global site tag (gtag.js) - Google Analytics