`
leiwuluan
  • 浏览: 707231 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

spring 事务管理

阅读更多

对于J2EE 应用程序而言,事务的处理一般有两种模式:

 

1 依赖特定事务资源的事务处理

这是应用开发中最常见的模式,即通过特定资源提供的事务机制进行事务管理。如通过JDBCJTA rollbackcommit方法;Hibernate Transaction rollbackcommit方法等。这种方法大家已经相当熟悉。

 

2 依赖容器的参数化事务管理

通过容器提供的集约式参数化事务机制,实现事务的外部管理。

 

Spring提供了一致的事务管理抽象。这个抽象是Spring最重要的抽象之一, 它有如下的优点:

 

(1)为不同的事务API提供一致的编程模型,如JTAJDBCHibernateiBATIS数据库层 JDO

(2)提供比大多数事务API更简单的,易于使用的编程式事务管理API

(3)整合Spring数据访问抽象

(4)支持Spring声明式事务管理

 

Spring事务管理能给我们带来什么?

对于传统的基于特定事务资源的事务处理而言(如基于JDBC 的数据库访问),Spring并不会对其产生什么影响,我们照样可以成功编写并运行这样的代码。同时,Spring还提供了一些辅助类可供我们选择使用,这些辅助类简化了传统的数据库操作流程,在一定程度上节省了工作量,提高了编码效率。

 

对于依赖容器的参数化事务管理而言,Spring 则表现出了极大的价值。Spring本身也是一个容器,只是相对EJB容器而言,Spring显得更为轻便小巧。我们无需付出其他方面的代价,即可通过Spring实现基于容器的事务管理(本质上来讲,Spring的事务管理是基于动态AOP)。

(1)编程式事务管理

使用TransactionTemplate

TransactionTemplate采用和其他Spring模板 ,如 HibernateTemplate一样的方法。它使用回调方法,把应用程序代码从处理取得和释放资源中解脱出来(不再有try/catch/finally)。如同 其他模板,TransactionTemplate是线程安全的。

 

示例:

 

UserDAO实现类

public class UserDAO implements IUserDAO {

    private TransactionTemplate transactionTemplate;

    private HibernateTemplate hibernateTemplate;

 

    public void setSessionFactory(

            SessionFactory sessionFactory) {

        this.transactionTemplate =

            new TransactionTemplate(

                    new HibernateTransactionManager(

                            sessionFactory)); 

        this.hibernateTemplate =

            new HibernateTemplate(sessionFactory);

    }

   

    public void insert(User user) {

        final User userData = user;

       

        transactionTemplate.setPropagationBehavior(

                TransactionDefinition.PROPAGATION_REQUIRED);

       

        transactionTemplate.execute(

          new TransactionCallbackWithoutResult() {

                protected void doInTransactionWithoutResult(

                        TransactionStatus status) {

                    try {

                        hibernateTemplate.save(userData);

                    }

                    catch(DataAccessException e) {

                        e.printStackTrace();

                        status.setRollbackOnly();

                    }

                }

            });

    }

 

    public User find(Integer id) {

        User user =

            (User) hibernateTemplate.get(User.class, id);

       

        return user;

    }

}

 

Test测试类

public class Test{

    public static void main(String[] args) {

        ApplicationContext context = new FileSystemXmlApplicationContext(

                    "beans-config.xml");

       

        IUserDAO userDAO =

            (IUserDAO) context.getBean("userDAO");

       

        User user = new User();

        user.setName("caterpillar");

        user.setAge(new Integer(30));

       

        userDAO.insert(user);

       

        user = userDAO.find(new Integer(1));

       

        System.out.println("name: " + user.getName());

    }

}

 

 

TransactionDefinition

隔离等级

描述

ISOLATION_DEFAULT

默认隔离等级

ISOLATION_READ_UNCOMMITTED

最低隔离等级,仅仅保证了读取过程中不会读取到非法数据

ISOLATION_READ_COMMITTED

某些数据库的默认隔离等级;保证了一个事务不会读到另外一个并行事务已修改但未提交的数据

ISOLATION_REPEATABLE_READ

比上一个更加严格的隔离等级。保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据

ISOLATION_SERIALIZABLE

性能代价最为昂贵,最可靠的隔离等级。所有事务都严格隔离,可视为各事务顺序执行

 

传播途径(Propagation Behavior)

 

Propagation Behavior

描述

PROPAGATION_REQUIRED

支持现有事务。如果没有则创建一个事务

 PROPAGATION_SUPPORTS

支持现有事务。如果没有则以非事务状态运行。

 PROPAGATION_MANDATORY

支持现有事务。如果没有则抛出异常。

 PROPAGATION_REQUIRES_NEW

总是发起一个新事务。如果当前已存在一个事务,则将其挂起。

PROPAGATION_NOT_SUPPORTED

不支持事务,总是以非事务状态运行,如果当前存在一个事务,则将其挂起。

 PROPAGATION_NEVER

 不支持事务,总是以非事务状态运行,如果当前存在一个事务,则抛出异常。

 PROPAGATION_NESTED

如果当前已经存在一个事务,则以嵌套事务的方式运行,如果当前没有事务,则以默认方式(第一个)执行

(2)声明式事务管理

Spring也提供了声明式事务管理。这是通过Spring AOP实现的。

 

大多数Spring用户选择声明式事务管理。这是最少影响应用代码的选择, 因而这是和非侵入性的轻量级容器的观念是一致的。

 

示例:

 

Spring配置文件

    <bean id="dataSource"

          class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName">

            <value>com.mysql.jdbc.Driver</value>

        </property>

        <property name="url">

            <value>jdbc:mysql://localhost:3306/test</value>

        </property>

        <property name="username">

            <value>root</value>

        </property>

        <property name="password">

            <value>root</value>

        </property> 

    </bean>

   

    <bean id="sessionFactory" 

          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"

          destroy-method="close">

        <property name="dataSource">

            <ref bean="dataSource"/>

        </property>

        <property name="mappingResources">

            <list>

                <value>com/pojo/User.hbm.xml</value>

            </list>

        </property>

        <property name="hibernateProperties">

            <props>

                <prop key="hibernate.dialect">

                    org.hibernate.dialect.MySQLDialect

                </prop>

            </props>

        </property>

    </bean>

 

    <bean id="userDAO" class="com.dao.UserDAO">

        <property name="sessionFactory">

            <ref bean="sessionFactory"/>

        </property>

    </bean>

 

    <bean id="transactionManager"

          class="org.springframework.orm.hibernate3.HibernateTransactionManager">

        <property name="sessionFactory">

            <ref bean="sessionFactory"/>

        </property>

    </bean>

       

    <bean id="userDAOProxy"

          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

        <property name="transactionManager">

            <ref bean="transactionManager"/>

        </property>

        <property name="proxyInterfaces">

            <list>

                <value>com.dao.IUserDAO</value>

            </list>

        </property>

        <property name="target">

            <ref bean="userDAO"/>

        </property>

        <property name="transactionAttributes">

            <props>

                <prop key="insert*">PROPAGATION_REQUIRED</prop>

            </props>

        </property>       

    </bean> 

 

UserDAO实现类

public class UserDAO implements IUserDAO {

    private HibernateTemplate hibernateTemplate;

   

    public void setSessionFactory(

            SessionFactory sessionFactory) {

        hibernateTemplate = new HibernateTemplate(sessionFactory);

    }

   

    public void insert(User user) {

        hibernateTemplate.save(user);

    }

 

    public User find(Integer id) {

        User user =

            (User) hibernateTemplate.get(User.class, id);

       

        return user;

    }

}

 

Test测试类

public class Test{

    public static void main(String[] args) {

        ApplicationContext context = new FileSystemXmlApplicationContext(

                    "beans-config.xml");

       

        IUserDAO userDAO =  (IUserDAO) context.getBean("userDAOProxy");

        User user = new User();

        user.setName("cater");

        user.setAge(new Integer(30));

       

        userDAO.insert(user);

       

        user = userDAO.find(new Integer(1));

       

        System.out.println("name: " + user.getName());

    }

}

 

 

配置中包含了dataSourcetransactionManager 等资源定义。这些资源都为一个名为userDAOProxy TransactionProxyFactoryBean 服务, userDAOProxy 则对包含实际数据逻辑的userDAO进行了事务性封装。

可以看到,在userDAOProxy "transactionAttributes"属性中,我们定义了针对userDAO 的事务策略,即将所有名称以insert 开始的方法(如UserDAO.insertUser方法)纳入事务管理范围。如果此方法中抛出异常,则Spring将当前事务回滚,如果方法正常结束,则提交事务。

而对所有名称以get 开始的方法(如UserDAO.getUser 方法)则以只读的事务处理机制进行处理。(设为只读型事务(readOnly),可以使持久层尝试对数据操作进行优化,如对于只读事务Hibernate将不执行flush操作,而某些数据库连接池和JDBC 驱动也对只读型操作进行了特别优化)。

 

 

分享到:
评论

相关推荐

    Spring事务管理Demo

    Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...

    Spring事务管理开发必备jar包

    本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理、编译工具以及与数据库交互的相关jar包。下面将对这些知识点进行详细解释: 1. **Spring框架*...

    spring事务管理

    ### Spring事务管理详解 #### 一、Spring事务管理概述 Spring框架提供了强大的事务管理功能,使得开发者能够更方便地管理应用程序中的事务。Spring事务管理主要包括两种类型:编程式事务管理和声明式事务管理。 -...

    spring 事务管理的理解

    Spring 框架是Java开发中...理解并熟练掌握Spring事务管理,对于提升应用程序的稳定性和可靠性至关重要。在实际开发中,结合声明式事务管理、事务传播行为、隔离级别和回滚规则,可以有效地确保数据的完整性和一致性。

    Spring事务管理.pdf

    Spring事务管理.pdf 1.资料 2.本地事务与分布式事务 3.编程式模型 4.宣告式模型

    Synchronized锁在Spring事务管理下线程不安全

    Synchronized锁在Spring事务管理下,导致线程不安全。

    Spring事务管理的jar包

    本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组操作,这些操作被视为一个整体,要么全部完成...

    Spring事务管理失效原因汇总

    标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...

    spring事务管理5种方法

    本篇文章将深入探讨Spring事务管理的五种方法,旨在帮助开发者更好地理解和运用这一核心特性。 首先,我们来了解什么是事务。在数据库操作中,事务是一组逻辑操作,这些操作要么全部成功,要么全部失败,确保数据的...

    Spring事务管理4种方式

    本文将详细介绍Spring事务管理的四种方式:编程式事务管理、声明式事务管理、PlatformTransactionManager接口以及TransactionTemplate。 1. **编程式事务管理**:这是一种手动控制事务的方式,通过在代码中调用`...

    详细介绍Spring事务管理

    ### Spring事务管理详解 #### 一、Spring事务管理的重要性及必要性 在现代软件开发中,事务管理是一项至关重要的技术,特别是在涉及数据库操作时。事务能够确保一系列操作要么全部成功,要么全部失败,这对于保持...

    spring事务管理.rar

    Spring事务管理是Spring框架的核心特性之一,它提供了一种强大且灵活的方式来管理应用程序中的事务边界。在企业级Java应用中,事务处理是确保数据一致性、完整性和可靠性的关键部分。本篇文章将深入探讨Spring的事务...

    spring事务管理.doc

    总的来说,Spring事务管理提供了一种灵活、强大的方式来处理应用程序中的事务,无论是在简单还是复杂的事务场景下,都能有效保证数据的一致性和完整性。通过声明式事务管理,开发者可以将关注点从事务细节中解脱出来...

    Spring事务管理

    Spring事务管理是Spring框架的核心特性之一,它提供了一种在Java应用中管理和协调数据库事务的标准方式。对于有Java基础的开发者来说,理解并掌握Spring事务管理至关重要,因为这有助于确保数据的一致性和完整性,...

    Spring事务管理配置文件问题排查

    当出现像描述中那样的问题——SQL语句执行出错但事务未回滚时,我们需要深入理解Spring事务管理的配置和机制。以下是一些关键知识点: 1. **Spring事务管理类型**: - **编程式事务管理**:通过`...

    spring事务管理几种方式代码实例

    spring事务管理几种方式代码实例:涉及编程式事务,声明式事务之拦截器代理方式、AOP切面通知方式、AspectJ注解方式,通过不同方式实例代码展现,总结spring事务管理的一般规律,从宏观上加深理解spring事务管理特性...

    Spring事务管理和SpringJDBC思维导图

    在思维导图"Spring Transaction.twd"中,可能包含了Spring事务管理的各个概念和它们之间的关系,如事务的ACID属性(原子性、一致性、隔离性和持久性),事务管理器,以及声明式和编程式事务管理的实现方式。...

    Spring事务管理的方法

    ### Spring事务管理的方法 #### 一、引言 在企业级应用开发中,事务管理是一项至关重要的技术。Spring框架作为Java领域中一个非常流行的轻量级框架,为开发者提供了多种方式来实现事务管理,其中主要分为编程式...

    spring事务管理1

    Spring事务管理确保每个事务都是独立的,防止了脏读、不可重复读和幻读等问题。脏读是指事务T1读取了事务T2未提交的修改;不可重复读是指事务T1在不同时间读取同一数据时得到不同结果,因为T2在这期间做了修改;幻读...

Global site tag (gtag.js) - Google Analytics