文档章节

Spring的事务管理难点剖析:应用分层的迷惑

JasonO
 JasonO
发布于 2016/01/27 17:59
字数 1231
阅读 13
收藏 0
点赞 1
评论 0

Web、Service及DAO三层划分就像西方国家的立法、行政、司法三权分立一样被奉为金 科玉律,甚至有的开发人员认为如果要使用Spring的事务 管理就一定要先进行三层的划分。这个看似荒唐的论调在开发人员中颇有市场。更有甚者,认为每层必须先定义一个接口,然后再定义一个实现类。其结果是:一个 很简单的功能,也至少需要3个接口和3个类,再加上视图层的JSP和JS等,打牌都可以围上两桌了,这种误解贻害不浅。
   对将“面向接口编程” 奉为圭臬,认为放之四海而皆准的论调,笔者深不以为然。是的,“面向接口编程”是Martin Fowler、Rod Johnson这些大师提倡的行事原则。如果拿这条原则去开发框架和产品,怎么强调都不为过。但是,对于我们一般的开发人员来说,做的最多的是普通工程项 目,往往只是一些对数据库增、删、查、改的功能。此时,“面向接口编程”除了带来更多的类文件外,看不到更多其他的好处。

  Spring框架所提供的各种好处(如AOP、注解增强、注解MVC等)的唯一前提就是让POJO的类变成一个受Spring容器管理的Bean,除此以 外没有其他任何的要求。下面的实例用一个POJO完成所有的功能,既是Controller,又是Service,还是DAO:

package com.baobaotao.mixlayer; 02   
03 import org.springframework.beans.factory.annotation.Autowired; 
04 import org.springframework.jdbc.core.JdbcTemplate; 
05 import org.springframework.stereotype.Controller; 
06 import org.springframework.web.bind.annotation.RequestMapping; 
07   
08 //①将POJO类通过注解变成Spring MVC的Controller 
09 @Controller
10 public class MixLayerUserService { 
11   
12     //②自动注入JdbcTemplate 
13     @Autowired
14     private JdbcTemplate jdbcTemplate; 
15   
16     //③通过Spring MVC注解映射成为处理HTTP请求的函数,同时作为一个拥有事务性的方法 
17     @RequestMapping("/logon.do") 
18     @Transactional
19     public String logon(String userName,String password){ 
20         if(isRightUser(userName,password)){ 
21             String sql = "UPDATE t_user u SET u.score = u.score + ? WHERE user_name =?"; 
22             jdbcTemplate.update(sql,20,userName); 
23             return "success"; 
24         }else{ 
25             return "fail"; 
26         } 
27     } 
28       
29     private boolean isRightUser(String userName,String password){ 
30         //do sth 
31         return true; 
32     } 
33 }

通过@Controller注解将MixLayerUserService变成Web层的Controller,同时也是Service层的服务类。此 外,由于直接使用JdbcTemplate访问数据,所以MixLayerUserService还是一个DAO。来看一下对应的Spring配置文件:

<?xml version="1.0" encoding="UTF-8" ?> 02 <beans xmlns="http://www.springframework.org/schema/beans"
03        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04        xmlns:context="http://www.springframework.org/schema/context"
05        xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
06        xmlns:tx="http://www.springframework.org/schema/tx"
07        
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
08     http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 
09     … 
10     <!--①事务管理配置-> 
11     <bean id="transactionManager" 
12           class="org.springframework.jdbc.datasource.DataSourceTransactionManager" 
13           p:dataSource-ref="dataSource"/> 
14     <tx:annotation-driven/> 
15   
16           
17     <!--②启动Spring MVC的注解功能-->
18     <bean class="org.springframework.web.servlet.mvc.annotation. 
19                   AnnotationMethodHandlerAdapter"/> 
20     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
21           p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/> 
22 </beans>

在①处,通过事务注解驱动使MixLayerUserService的logon()工作于事务环境下,②处配置了Spring MVC的一些基本设施。要使程序能够运行起来还必须进行web.xml的相关配置:

<?xml version="1.0" encoding="UTF-8"?> 02 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
03     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
05     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
06     <context-param> 
07         <param-name>contextConfigLocation</param-name> 
08         <param-value>classpath:com/baobaotao/mixlayer/applicationContext.xml</param-value> 
09     </context-param> 
10     <context-param> 
11         <param-name>log4jConfigLocation</param-name> 
12         <param-value>/WEB-INF/classes/log4j.properties</param-value> 
13     </context-param> 
14   
15     <listener> 
16         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
17     </listener> 
18     <listener> 
19         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
20     </listener> 
21   
22     <servlet> 
23         <servlet-name>user</servlet-name> 
24         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
25         <init-param> 
26             <param-name>contextConfigLocation</param-name> 
27             <param-value>classpath:com/baobaotao/mixlayer/applicationContext.xml</param-value> 
28         </init-param> 
29         <load-on-startup>1</load-on-startup> 
30     </servlet> 
31     <servlet-mapping> 
32         <servlet-name>user</servlet-name> 
33         <url-pattern>*.do</url-pattern> 
34     </servlet-mapping> 
35 </web-app>

这个配置文件很简单,唯一需要注意的是DispatcherServlet的配置。默认情况下Spring MVC根据Servlet的名字查找WEB-INF下的<servletName>-servlet.xml作为Spring MVC的配置文件,在此,我们通过contextConfigLocation参数显式指定Spring MVC配置文件的确切位置。
   将org.springframework.jdbc及org.springframework.transaction的日志级别设置为DEBUG,启 动项目,并访问http://localhost:8088/chapter10/logon.do?userName=tom应 用,MixLayerUserService#logon方法将作出响应,查看后台输出日志,如下所示:

引用
Returning cached instance of singleton bean 'transactionManager'
  Creating new transaction with name [com.baobaotao.mixlayer.MixLayerUserService.logon]:   
    PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
(DataSourceTransactionManager.java:204) - Acquired Connection [jdbc:mysql://localhost:3306/sampledb, UserName=root@localhost , MySQL-AB JDBC Driver] for JDBC transaction
(DataSourceTransactionManager.java:221) - Switching JDBC Connection [jdbc:mysql://localhost:3306/sampledb, UserName=root@localhost , MySQL-AB JDBC Driver] to manual commit
(JdbcTemplate.java:810) - Executing prepared SQL update
(JdbcTemplate.java:569) - Executing prepared SQL statement [UPDATE t_user u SET u.score = u.score + ? WHERE user_name =?]
(JdbcTemplate.java:819) - SQL update affected 0 rows
(AbstractPlatformTransactionManager.java:752) - Initiating transaction commit
(DataSourceTransactionManager.java:264) - Committing JDBC transaction on Connection [jdbc:mysql://localhost:3306/sampledb, UserName=root@localhost , MySQL-AB JDBC Driver]

   日志中红色部分说明了MixLayerUserService#logon方法已经正确运行在事务上下文中。


本文转载自:http://blog.csdn.net/abc19900828/article/details/39498731

共有 人打赏支持
JasonO
粉丝 7
博文 30
码字总数 6403
作品 0
深圳
高级程序员
Spring 事务管理高级应用难点剖析: 第 1 部分

Spring 最成功,最吸引人的地方莫过于轻量级的声明式事务管理,仅此一点,它就宣告了重量级 EJB 容器的覆灭。Spring 声明式事务管理将开发者从繁复的事务管理代码中解脱出来,专注于业务逻辑...

红薯 ⋅ 2010/03/28 ⋅ 2

Spring的事务管理难点剖析(2):应用分层的迷惑

Web、Service及DAO三层划分就像西方国家的立法、行政、司法三权分立一样被奉为金科玉律,甚至有的开发人员认为如果要使用Spring的事务 管理就一定要先进行三层的划分。这个看似荒唐的论调在开...

icheer ⋅ 2012/07/17 ⋅ 0

Spring的事务管理难点剖析(1):DAO和事务管理的牵绊

有些人很少使用Spring而不使用Spring事务管理器的应用,因此常常有人会问:是否用了Spring,就一定要用Spring事务管理器,否则就无法进行数据的持久化操作呢?事务管理器和DAO是什么关系呢?...

icheer ⋅ 2012/07/17 ⋅ 0

springmvc中的事务操作

spring的事务有两种一种是声明式事务,一种是编程式事务。在这里主要说一下申明式事务。 1、首先页面分层需要规范一些,controller只负责与前端的数据交互方面,逻辑处理程序放在service层中...

JavionXiong ⋅ 04/26 ⋅ 0

基于可靠消息方案的分布式事务(二):Java中的事务

前言:在上一篇文章 基于可靠消息方案的分布式事务:Lottor介绍 中介绍了常见的分布式事务的解决方案以及笔者基于可靠消息方案实现的分布式事务组件Lottor的原理,并展示了应用的控制台管理。...

aoho ⋅ 06/01 ⋅ 0

Spring高级事务管理难点剖析

1Spring事务传播行为 所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring支持7种事务传播行为 PROPAGATION_REQUIRED(加入已有事务) 如果当前没有事务,就新建...

蛙牛 ⋅ 2014/08/23 ⋅ 12

@Transaction必知必会

1. Spring事务的基本原理 事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编码式和声明式的两种方式。编程式事务指的是通过编码方式...

maskwang520 ⋅ 04/15 ⋅ 0

Spring AOP 日志拦截器的事务管理

如果要在方法执行前或后或抛出异常后加上一个自己的拦截器,或者一个环绕拦截器,在拦截器中执行一些操作,比如执行一些数据库操作,记录一些信 息,这些操作通过调用一个服务类的方法来执行...

哲别0 ⋅ 05/18 ⋅ 0

Spring编程式和声明式事务

1.编程式事务 1.1 编程式和声明式事务的区别 Spring提供了对编程式事务和声明式事务的支持,编程式事务允许用户在代码中精确定义事务的边界,而声明式事务(基于AOP)有助于用户将操作与事务...

梨加橙 ⋅ 06/19 ⋅ 0

技术贴网址记录

1、Hibernate 3 深度解析: 地址:http://www.ibm.com/developerworks/cn/java/j-lo-hibernate3/ 2、使用 Spring 2.5 基于注解驱动的 Spring MVC: 地址:http://www.ibm.com/developerworks......

LvCreator ⋅ 2013/12/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 48分钟前 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 55分钟前 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

Linux(CentOS)下配置php运行环境及nginx解析php

【part1:搭建php环境】 1.选在自己需要安装的安装包版本,wget命令下载到服务器响应目录 http://php.net/releases/ 2.解压安装包 tar zxf php-x.x.x 3.cd到解压目录执行如下操作 cd ../php-...

硅谷课堂 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部