Spring事务管理

什么是事务

在应用程序中,事务是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元)。事务划分边界,并且在这些边界内的所有操作都受到约束,并作为单个工作单元执行。

事务管理的问题

你可以根据自己的需求来管理事务,可以自己管理事务或使用EJB容器托管事务。如果使用JDBC则可以选择JDBC的事务管理API;那么对于Hibernate,你将选择hibernate事务管理API;如果在应用中使用全局事务,你将使用JTA(Java事务API)。

如果使用全局事务,你可以用于多个事务资源(如关系数据库和消息队列),你将通过JTA管理事务。

如果使用本地事务(如与JDBC连接关联的事务),则将使用JDBC事务管理API。本地事务的问题在于它们不能跨多个事务资源工作。例如,使用JDBC连接管理事务的代码无法在全局JTA事务中运行。本地事务的另一个问题是它们是侵入性的,即你将在代码中包含所有事务代码。

在代码中使用JDBC事务的方法如下:

try{
 connection.setAutoCommit(false);

 ...
 ...

 connection.commit(); // for committing transaction
}catch(SQLException exp){
 // transaction rollback
 connection.rollback();
}

Spring事务管理

Spring Framework为事务管理提供了一个统一的抽象层来隐藏底层事务管理API,从而为不同的事务API提供一致的编程模型,例如Java Transaction API(JTA),JDBC,Hibernate和Java Persistence API(JPA)。

使用Spring事务管理,你只需编写一次代码,就可以在不同环境中的不同事务管理策略中使用它。

Spring事务也是对EJB事务的重大改进,因为可以将POJO与Spring事务一起使用。除非使用分布式事务,否则您甚至不需要Spring事务的应用程序服务器。

如何在Spring事务管理中实现抽象

Spring事务管理中的抽象是通过org.springframework.transaction.PlatformTransactionManager 接口实现的。

public interface PlatformTransactionManager {
 TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
 void commit(TransactionStatus status) throws TransactionException;
 void rollback(TransactionStatus status) throws TransactionException;
}

在接口中,getTransaction()方法返回一个TransactionStatus对象,该对象表示事务的状态,如果存在匹配的事务,它可能表示新事务或现有事务。getTransaction()方法中传递的参数是TransactionDefinition的一个实例。

TransactionDefinition定义Spring事务的属性,包含如下内容:

  • Propagation - 定义事务的传播行为。例如,您可以指定某一行为以便代码可以继续在现有事务中运行,或者可以暂停现有事务并创建新事务。
  • Isolation - 此属性定义此事务与其他事务的工作隔离的程度。例如,此事务是否可以看到来自其他事务的未提交的写入?
  • Timeout - 此事务在由基础事务进行自动回滚之前运行多长时间。
  • Read-only status - 当你的代码只读取但不修改数据时,可以使用只读事务。

请参阅Spring事务属性 - 传播和隔离级别设置,以了解Spring事务管理中的各种传播和隔离级别设置。

在Spring事务中定义事务管理器

Spring中的事务管理器是PlatformTransactionManager,通过它在Spring事务管理中抽象事务,但是你需要定义正确的PlatformTransactionManager实现。

PlatformTransactionManager实现通常需要了解它们工作的环境:JDBC,JTA,Hibernate等。以下是不同环境的实现类。

Spring框架中的PlatformTransactionManager实现:

  • DataSourceTransactionManager - 单个JDBC DataSource的PlatformTransactionManager实现。
  • HibernateTransactionManager - 用于单个Hibernate SessionFactory的PlatformTransactionManager实现。
  • JmsTransactionManager - 单个JMS ConnectionFactory的PlatformTransactionManager实现。
  • JpaTransactionManager - 单个JPA EntityManagerFactory的PlatformTransactionManager实现。
  • JtaTransactionManager - JTA的PlatformTransactionManager实现,委托给后端JTA提供程序。
  • WebLogicJtaTransactionManager - BEA WebLogic(9.0及更高版本)的特殊JtaTransactionManager变体。
  • WebSphereUowTransactionManager - 委托给UOWManager实例的特定于WebSphere的PlatformTransactionManager实现。

以下是一些示例,说明如何为不同的环境定义TransactionManager。

TransactionManager for JDBC
通过引用定义的DataSource来定义。

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

TransactionManager for Hibernate

<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

TransactionManager for JPA

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <propertyname="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

TransactionManager for JTA

<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" />

Spring事务管理类型

Spring Transaction Management支持程序式事务管理和 声明式事务管理。

程序式事务管理

Spring Framework提供了两种程序化事务管理方法:

  • 使用TransactionTemplate。
  • 直接使用PlatformTransactionManager实现。

如果要使用TransactionTemplate,则可以通过提供事务管理器的引用来按如下方式对其进行配置。

<propertyname="transactionTemplate">
    <bean class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="txManager" />
    </bean>
</propertyname>

声明式事务管理

通过对Spring事务管理使用声明性事务,可以将事务管理与业务代码分开。您可以使用AOP使用注解或基于XML的配置来定义声明性事务。

用于声明式事务管理的注解是@Transactional。你可以在接口定义,接口上的方法,类定义或类的公共方法之前放置@Transactional。

要使Spring框架能使用@Transactional注解,你必须在XML配置中定义<tx:annotation-driven />元素。

<tx:annotation-driven transaction-manager="txManager"/>

如果使用Java配置,则可以通过将@EnableTransactionManagement添加 到配置类来启用@Transactional注解支持。

@Configuration
@EnableTransactionManagement
public class AppConfig{
    ...
    ...
}

Spring建议您只使用@Transactional注解来注解具体类(以及具体类的方法),而不是注解接口。

Spring框架中的@Transactional设置

您可以提供事务属性,如传播行为,隔离级别以及@Transactional注解。@Transactional注解的完整属性如下 :

  • propagation - 可选的传播设置。
  • isolation - 可选隔离级别。仅适用于传播REQUIRED或REQUIRES_NEW。
  • timeout - 可选的事务超时。仅适用于传播REQUIRED或REQUIRES_NEW。使用int值以秒为单位定义。
  • readOnly - 读/写与只读事务。仅适用于REQUIRED或REQUIRES_NEW。
  • rollbackFor -导致回滚的可选异常类数组。
  • rollbackForClassName - 导致事务回滚的异常类名字数组。
  • noRollbackFor - 不会导致回滚的可选异常类数组。
  • noRollbackForClassName - 不会导致事务回滚的异常类名字数组。

默认的@Transactional设置如下:

  • Propagation设置为PROPAGATION_REQUIRED。
  • 隔离级别为ISOLATION_DEFAULT。
  • 事务是读/写。
  • 事务超时默认为基础事务系统的默认超时,如果不支持超时,则默认为none。
  • 任何RuntimeException都会触发回滚,而任何检查的Exception都不会。

使用@Transactional注释的示例

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public class TestService implements FooService {
 public Foo getValue(String Id) {
  // do something
 }
 // these settings have precedence for this method
 @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, timeout=60, rollbackFor=ValueNotFoundException.class)
 public void updateValue(Person person) {
  // do something
 }
}

TestService类使用了@Transactional注解,该注解适用于类中所有方法将支持事务并且所有方法是只读的。方法updateValue通过拥有自己的@Transactional注解来覆盖它,该注解创建一个新事务,如果抛出ValueNotFoundException,则只读为false并且事务被回滚。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

peterwanghao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值