`

Spring中的数据库操作事务

    博客分类:
  • SSH
阅读更多

一、 Spring 中的事务

Spring 为什么提供对事务的支持?还记得我们在编写 OA 项目时,为了统一处理一类事务的多个 Dao 方法对数据库的操作是在一个事务中进行的,我们添加了一个“ *.do” 的过滤器,在过滤器中使用当前线程( ThreadLocal )的 Session 来处理事务。

 

其中我们也曾提到过将事务统一在过滤器中只是为解决一时之需,将事务统一放在 Service 的方法中才是优雅的做法。我们使用 Spring 就可以实现将事务统一放在 Service 的方法上。

 

1. Spring 中引入事务

通过外部 Bean 引入数据源我就不再做总结了,这里直接列出引入 Spring 中事务类的方法。下面为引入 Jdbc 的事务管理:

<bean name="transactionManager"

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

<property name="dataSource" ref="dataSource" />

</bean>


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

tx” 元素指定使用注解进行事务处理的 Bean

 

引入 Hibernate 的事务管理:

<bean id="sessionFactory"

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

<property name="dataSource" ref="dataSource" />

</bean>


<bean id="transactionManager"

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

<property name="sessionFactory" ref="sessionFactory" />

</bean>


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

2. 使用 Spring 的事务

Service 方法上添加事务注解“ @Transactional ,此时的 Service 方法便具有了事务管理。这正是使用 AOP 的编程思想,在过滤器上添加事务统一管理,也正是 AOP 的思想。

 

事务的传播性,当一个具有 事务的方法调用另一个具有事务的方法时。此时可以设置事务的传播属性,实现不同的需求。事务的传播性有:

传播属性

描 述

REQUIRED

如 果有事务在运行,当前的方法就在这个事务内运行,否则启动一个新的事务,并在自己的事务内运行。

REQUIRED_NEW

当前的方法必须启动新的事务,并在它自己的事务内运行。如果有事务正在运行,则将它挂起。

SUPPORTS

如果有事务在运行,当前的 方法就在这个事务内运行。否则它可以不运行在事务中。

NOT_SUPPORTED

当前的方法 不运行在事务中。如果有运行的事务,将它挂起。

MANDATORY

当前的方法运行在事务内容,如果没有 正在运行的事务,则抛异常。

NEVER

当前的方法不应该运行在事 务中。如果有运行的事务,则抛异常。

NESTED

如果有事务在运行,当前的方法在这个事务的嵌套事务内运行。否则,启动一个新的事 务,并在它自己的事务内运行。

前两项是常用的。

 

Transactional 注解所具有的属性:

 

 

@Transactional(propagation=Propagation.REQUIRES_NEW, // 事务传播属性

isolation=Isolation.READ_COMMITTED,// 事务隔离级别

rollbackFor=Exception.class,// 异常回滚

unrollbackFor=IOException.class,// 异常不回滚

timeout=2, // 超时事务

readOnly=false)// 只读事务
 

 

 

属性

类型

描述

propagation

枚举型: Propagation

可选的传播性设置

isolation

枚举型: Isolation

可选的隔离性级别(默认值: ISOLATION_DEFAULT

readOnly

布尔型

读写型事务 vs. 只读型事务。只读型事务一般用于查询。

timeout

int 型(以秒为单位)

事务超时,如果在指定时间内没有完成 事务,事务则回滚。

rollbackFor

一组 Class 类的实例,必须是 Throwable 的子类

一组异常类,遇到时 必须 进行回滚。默认情况下 checked exceptions 不进行回滚,仅 unchecked exceptions (即 RuntimeException 的子类)才进行事务回滚。

rollbackForClassname

一组 Class 类的名字,必须是 Throwable 的子类

一组异常类名,遇到时 必须 进行回滚

noRollbackFor

一组 Class 类的实例,必须是 Throwable 的子类

一组异常类,遇到时 必须不 回滚。

noRollbackForClassname

一组 Class 类的名字,必须是 Throwable 的子类

一组异常类,遇到时 必须不 回滚

 

使用 XML 文件配置 Spring 事务:

<tx:advice id="testTransaction" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="methodName" propagation="REQUIRED"

read-only="false" rollback-for="Expetion" timeout="2" isolation="READ_COMMITTED" />

</tx:attributes>

</tx:advice>


<aop:config>

<aop:pointcut expression="execution(* cn.itcast.cc.spring.transaction.*.*(..))"

id="aopTransaction" />

<aop:advisor advice-ref="testTransaction" pointcut-ref="aopTransaction" />

</aop:config>
 

二、 Spring 整 合 Hibernate

Spring 支持大多数流行的 ORM 框架,包括 HibernateJDO TopLink Ibatis JPA 。它这些 ORM 框架的支持是一致的,因此可以把和 Hibernate 整合技术应用到其他 ORM 框架上。 Spring2.0 同时支持 Hibernate2.x 3.x 。但 Spring2.5 只支持 Hibernate3.1 或更高版本

 

1. Spring 中配置 SessionFactory

<bean id="sessionFactory"

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

<property name="dataSource" ref="dataSource" />

</bean>
 

其中的 DataSource 是我们在第一天就讲到的使用外部 Bean 配置数据源。

 

虽然我们使用的数据源是一个 Bean ,它涉及到 Hibernate 私有配置的信息被声明在“ hibernate.cfg.xml” 文件中。但现在我们可以这个外在的“ hibernate.cfg.xml” 文件,我们需要在上面的 baen 中添加:


<bean id="sessionFactory"

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

<property name="dataSource" ref="dataSource" />

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

<prop key="hibernate.hbm2ddl.auto">update</prop>

</props>

</property>

<property name="mappingResources">

<list>

<value>cn/itcast/spring/hibernate/Customer.hbm.xml</value>

</list>

</property>

</bean>
 

OK SessionFactory 已经被我们整合进来了!十分简单,跟其他的类一样。

 

还记得我们昨天使用的 JdbcTemplate 吗?那是 Spring JDBC 提供的支持, Spring 也有为 Hibernate 提供支持:

支持类

JDBC

Hibernate

模板类

JdbcTemplate

HibernateTemplate

DAO 支持类

JdbcDaoSupport

HibernateDaoSupport

事务管理类

DataSourceTransactionManager

HibernateTransactionManager

 

使用 HibernateTemplate ,需要声明一个 Bean

< bean id = "hibernateTemplate" class = "org.springframework.orm.hibernate3.HibernateTemplate" >

< property name = "sessionFactory" ref = "sessionFactory" />

</ bean >

 

 

DAO 支持类对我们来说比较陌生, HibernateDAO 可以通过继承 HibernateDaoSupport 来继承 setSessionFactory() setHibernateTemplate() 方法。然后,只要在 DAO 方法中调用 getHibernateTemplate() 方法就可以获取到模板实例。

 

三、 Spring 整 合 Struts1.x

 

1 . 通过注册 Servlet 监听器 ContextLoaderListener Web 应用程序可以加载 Spring ApplicationContext 对象。这个监听器会将加载好的 ApplicationContext 对象保存到 Web 应用程序的 ServletContext 中。随后, Servlet 或可以访问 ServletContext 的任意对象就能通过一个辅助方法来访问 Spring 的应用程序上下文了。

 

<context-param>

<param-name>contextConfigFile</param-name>

<param-value>beans.xml</param-value>

</context-param>

<listener>

<listener-class>cn.itcast.cc.spring.SpringServletContextListener</listener-class>

</listener>
 

SpringServletContextListener contextInitialized 方法中

public void contextInitialized(ServletContextEvent arg0) {

String cfgFile = arg0.getServletContext().getInitParameter("contextConfigFile");

ApplicationContext ac = new ClassPathXmlApplicationContext(cfgFile);

arg0.getServletContext().setAttribute("applicationContext", ac);

}
 

以后在 Action 中需要使用 SpringIOC 容器中的 Bean 时,就可以先到 ServletContext 中去获取 ApplicationContext ,然后再获取相应的 Bean

 

2 . web.xml 文件中注册 Spring 提供的 Servlet 监听器 ContextLoaderListener ,它会在当前 web 应用被加载时将 Spring ApplicationContext 保存到 ServletContext 对象中。

 

ContextLoaderListener 监听器通过查找 web 应用初始化参数 contextConfigLocation 来获取 Bean 配置文件的位置。如果有多个 Bean 配置文件,可以通过逗号或空格进行分隔。 contextConfigLocation 的默认值为 /WEB-INF/applicationContext.xml 。若实际的文件和默认值一致则可以省略这个 web 应用的初始化参数。

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:beans.xml</param-value>

</context-param>


<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>


 

在需要 Bean Action Servlet 中获取 Bean 的方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());

ac.getBean("beanName");

}
 

3 . 通过注册 Servlet 监听器 ContextLoaderListener Struts 应用程序能够加载 Spring ApplicationContext 对象,并像在通用的 Web 应用程序中那样在 Servlet 上下文中对它进行访问。然而, Spring 还提供了更好的,特定于 Struts 的解决方案。

  1. struts 配置文件中注册 Struts 插件来加载应用程序上下文,它会自动引用 Servlet 监听器加载的应用程序上下文作为它的父上下文,以便可以引用其中声明的 Bean

  2. <plug-in  className="org.springframework.web.struts.ContextLoaderPlugIn">
    
    <set-property property="contextConfigLocation"
    
    value="classpath:struts-config.xml,classpath:beans.xml" />
    
    </plug-in>
     

    1. Spring 提供了一个 ActionSupport 对象,这是 Action 类的一个子类,通过它的 getWebApplicationContext() 方法可以获取到 Spring 的应用程序上下文。

public  class LoginAction extends ActionSupport {


@Override

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

ApplicationContext ac = this.getWebApplicationContext();

HelloSpring hs = (HelloSpring) ac.getBean("helloSpring");

request.setAttribute("message", hs.hello("changcheng"));

return mapping.findForward("success");

}

}
 
  1. spring 的应用程序上下文中声明 Struts Action 对象,使用 Spring 的依赖注入来注入 Spring 应用程序上下文的其他 Bean

 

我们的 Action 类:

public  class LoginAction extends Action {

private HelloSpring helloSpring;

public void setHelloSpring(HelloSpring hs) {

this.helloSpring = hs;

System.out.println("*****注入*****:" + this.helloSpring);

}


@Override

public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response)

throws Exception {

request.setAttribute("message", this.helloSpring.hello("changcheng"));

return mapping.findForward("success");

}

}
 

struts-config.xml 中将的 Action 配置为:

<action-mappings>

<action path="/login">

<forward name="success" path="/success.jsp" />

</action>

</action-mappings>


<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor" />
 

beans.xml 中配置:

<bean  id="helloSpring"  class="cn.itcast.cc.spring.struts.hello.HelloSpring"  />

<bean name="/login" class="cn.itcast.cc.spring.struts.action.LoginAction">

<property name="helloSpring" ref="helloSpring"/>

</bean>
 

这种方法也需要“ 1)” plug-in

 

四、 SSH 整合( Spring Struts1.x Hibernate

将上面的二和三放到一起就是 SSH 整合,佟老师使用一个使用注册的例子演示 SSH 整合。我只简单说一下思想吧!

 

1). 创建动态 WEB 工程。

2). web.xml 添加 spring 的“ ContextLoaderListener 监听器和 Struts ActionServlet

3). Spring 的配置文件中引入数据源和 Hibernate SessionFactory HibernateTransactionManager

4). struts 添加 spring 的“ DelegatingRequestProcessor 制器。

5). Action Service Dao 添加 Spring AOP 注解。

1
0
分享到:
评论

相关推荐

    spring事务与数据库操作

    ### Spring事务与数据库...- **配置事务规则**:最后,需要配置事务规则,指定哪些方法需要在事务中执行。 ##### 1.3 示例代码 下面是一个简单的示例,展示了如何使用XML配置文件来配置Spring的声明式事务: ```xml ...

    Spring Boot数据库事务控制.zip

    在Spring Boot中,数据库事务控制是实现业务逻辑一致性的重要手段。本资料主要围绕Spring Boot如何进行数据库事务管理进行深入探讨。 首先,我们需要了解什么是事务。事务是数据库操作的基本单位,它保证了一组...

    spring boot 常用数据库操作例子

    这意味着,如果一个方法被标记为`@Transactional`,那么它的所有数据库操作将在同一个事务中执行,确保数据的一致性。 综上所述,这个示例提供了Spring Boot和JPA结合使用的基本用法,包括多数据库支持、存储过程...

    spring对多个数据库进行事务管理.doc

    Spring 框架确实提供了对多个数据库事务管理的支持,这对于多数据源的应用场景非常关键。在Spring中,事务管理可以通过编程式和声明式两种方式进行。编程式事务管理需要程序员手动控制事务的开始、提交、回滚等操作...

    Spring综合实例 spring配置oracel数据库 事务管理 切面

    Spring综合实例 spring配置oracel数据库 事务管理 切面 业务描述:实现用户简单的注册登录功能。 用户注册时候需要输入用户名,密码,邮箱地址,点击注册后成功。 用户登录时可以选择使用用户名或者邮箱地址进行...

    spring连接数据库实例

    Spring还提供了`TransactionManagement`功能,可以方便地管理数据库事务。在Spring配置中启用事务管理器,并在需要事务的方法上添加`@Transactional`注解,Spring会自动进行事务的开始、提交或回滚。例如: ```xml ...

    spring和数据库层的结合

    在这个过程中,Spring负责管理DAO实例的生命周期以及事务处理,而Struts则负责接收用户的输入并调用相应的业务逻辑。 #### 二、Spring与JDBC的集成 **JDBC (Java Database Connectivity)** 是Java中用于与数据库...

    spring常用数据库事务传播属性和事务隔离级别1

    即使外部方法在一个事务中,内部方法也会独立地在自己的事务中运行,互不影响。 3. **Propagation.SUPPORTS**:如果当前存在事务,就支持它;如果不存在,也不会抛出异常,而是以非事务的方式运行。 4. **...

    Spring事务传播原理及数据库事务操作原理.rar

    本资料主要探讨了Spring事务的传播原理以及数据库事务的操作原理,这对于理解和使用Spring框架进行事务处理至关重要。 首先,让我们深入理解Spring事务的传播行为。在Spring中,事务的传播行为是指在一个事务方法被...

    Spring-test做数据库操作的单元测试2-跨库访问

    综上所述,"Spring-test做数据库操作的单元测试2-跨库访问"这个主题涵盖了许多关键概念,包括Spring-test的运行机制、多数据源配置、事务管理以及测试的准备与清理。这些知识点对于开发涉及跨库操作的应用程序,确保...

    spring多数据库

    在Spring框架中,多数据库的支持是一项重要的功能,它允许开发者在一个应用中同时连接并操作多个数据库。这在处理跨系统数据交互、数据隔离或者不同数据源的场景下非常有用。"spring多数据库"项目就是针对这种需求而...

    Spring中连接各个数据库

    - 虽然在给定的内容中没有提及,但通常在Spring应用中,还需要配置事务管理器,比如`PlatformTransactionManager`,以便处理数据库操作的事务边界。这可以通过`&lt;tx:annotation-driven&gt;`或`&lt;bean&gt;`标签来实现,并将`...

    Spring事务操作示例(四种方式)

    Spring事务操作示例(四种方式),包含完整代码和数据库文件(基于MySQL,在项目sql文件夹中),可运行,学习Spring事务详见博客:http://blog.csdn.net/daijin888888/article/details/51822257

    02-01-10-Spring事务传播原理及数据库事务操作原理1

    在本课程中,我们将深入探讨Spring事务传播原理和数据库事务操作的基本概念,这对于有Spring开发经验的人员来说,是进一步深化事务控制理解的关键。我们还将触及分布式事务的初步知识,帮助开发者更好地掌握基于...

    Spring事务管理Demo

    3. 业务逻辑:在事务中执行相关的数据库操作。 4. 提交或回滚事务:如果所有操作成功,事务将被提交;如果有异常,事务将被回滚。 在压缩包中的Spring事务管理练习,你可以尝试创建一个简单的示例,例如模拟两个...

    初学SpringCloud连接Oracle数据库

    至此,你已经具备了在SpringCloud中连接Oracle数据库并进行数据操作的基础知识。在实际项目中,你可能还需要考虑事务管理、数据缓存、数据库分页、性能优化等方面的问题。确保对这些概念有深入理解,能够帮助你更好...

    spring操作MySQL数据库.zip

    在本项目"spring操作MySQL数据库.zip"中,主要展示了如何使用Spring框架与MySQL数据库进行集成,实现对数据库的增删查改操作。Spring是Java领域一个广泛应用的开源框架,它提供了一个全面的编程和配置模型,使得开发...

    Spring事务流程图

    Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。在Spring中,事务管理分为编程式和声明式两种方式。本篇文章将详细解释Spring事务管理的流程,以及如何通过时序图来理解这一...

    spring框架、数据库池连接等之间连接的jar包.rar

    在Spring框架中,数据库连接池是实现高效数据库操作的关键组件,它允许应用程序重复使用已建立的数据库连接,而不是每次都创建新的连接,从而提高了性能和资源利用率。 在Java中,常见的数据库连接池工具有C3P0、...

Global site tag (gtag.js) - Google Analytics