javascript
Spring的事务管理难点剖析:应用分层的迷惑
2019獨角獸企業重金招聘Python工程師標準>>>
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/txhttp://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方法已經正確運行在事務上下文中。
轉載于:https://my.oschina.net/u/2317118/blog/610551
總結
以上是生活随笔為你收集整理的Spring的事务管理难点剖析:应用分层的迷惑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CI框架 -- CLI执行php代码
- 下一篇: flash _currentframe+