`
thaIm
  • 浏览: 90069 次
  • 性别: 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-framework-5.0.4.RELEASEspring-framework-5.0.4.RELEASE

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

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

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

    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-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 jar 包详解

    使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。 (4) spring-context.jar 这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ...

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例

    使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。 (4) spring-context.jar  这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ...

    spring-aop.jar

    這個jar檔包含在應用中使用Spring的AOP特性時所需的類。使用基於AOP的Spring特性,如聲明型事務管理(Declarative Transaction Management),也要在應用裡包含這個jar包。

    spring4.3.9相关jar包

    使用基于AOP 的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。 外部依赖spring-core, (spring-beans,AOP Alliance, CGLIB,Commons Attributes)。 spring-...

    Getting.started.with.Spring.Framework.2nd.Edition1491011912.epub

    - Programmatic and declarative transaction management - Spring Web MVC - Developing RESTful Web Services using Spring - Spring Security The book shows a simple internet banking application that is ...

    最新最全的spring开发包

    使用基于AOP的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。 (4) spring-context.jar 这个jar文件为Spring核心提供了大量扩展。可以找到使用Spring ...

    spring-framework-reference-4.1.2

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    spring-framework-reference4.1.4

    3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................

    spring framework 4.2 jar包及全部源码文档

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

    Spring攻略(第三版)源代码

    12. Spring Transaction Management 13. Spring Batch 14. Spring NoSQL and Big Data 15. Spring Java Enterprise Services and Remoting Technologies 16. Spring Messaging 17. Spring Integration 18. Spring ...

    RESTful-API后台系统架构设计(Java).doc

    RS 2.0 Implementation 中间层: Spring Beans - IoC Container Spring Transaction - Transaction Management Dozer - Bean Transformation Framework Spring Security - Security Framework Quartz Scheduler - ...

    Spring.Persistence.with.Hibernate.2nd.Edition.1484202694

    Learn how to use the core Hibernate APIs and tools as part of the Spring Framework....Chapter 6: Transaction Management Chapter 7: Effective Testing Chapter 8: Best Practices and Advanced Techniques

    Spring.Essentials.178398

    Explore Spring's comprehensive transaction support for declarative Transaction Management and its integration with Spring's data access abstractions Investigate Spring Data access mechanisms with ...

    Spring Framework API文档

    Spring Framework API文档。...它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transaction Management,等等......

    Learning Spring 5.0

    Understand how to manage cross-cutting with logging mechanism, transaction management, and more using Aspect-oriented programming Explore Spring MVC and know how to handle requesting data and ...

    pro Spring

    Learn how to replace common EJB features with Spring alternatives, including Spring's comprehensive AOP-based transaction management framework. Learn to integrate and use these other open source ...

Global site tag (gtag.js) - Google Analytics