I. Knowledge points and problems
Back-end Frame:
Spring, spring MVC, MyBatis
Business requirements:
Client first from the server to obtain a large number of user information to the client, after editing the unified post to the server, the data changes are either full success or failure, so need to use transaction support.
Problem:
A spring declarative transaction is configured, and an exception in the run is not rolled back. Getting Started from the web is a problem with your configuration, because the load order of the configuration files determines that the container's loading order causes the spring transaction to not work.
Details such as the following:
Because of the use of SPRINGMVC, MyBatis, so the unified use of annotations to declare service, Controller
Because the server starts when the configuration file is loaded in the Order of Web.xml-root-context.xml (Spring configuration file)-servlet-context.xml (Springmvc profile). Because the controller in the Root-context.xml configuration file will first scan the assembly. At this point, however, the service has not been processed for transactional enhancement, and the resulting service will be provided as-is (without transaction enhancement and therefore no transaction processing power). So we must not scan the controller in Root-context.xml.
The above problem was not rolled back, and it was later learned that Spring would only trigger a rollback if the unchecked (runtimeexception) exception occurred in the program's run. Because it is a server that interacts directly with the client, the result of each processing is to be fed back to the client in the form of a errorcode error code and a MSG error message, so that all exceptions are explicitly captured. and sends the information to the client in JSON data format, which causes the transaction not to roll back when an exception occurs.
Because to give the client the most real, accurate error feedback and have to catch the possible anomalies and fall into the meditation. Of course, the problem always has a way of solving, even walking around.
After the query from the data obtained, capture can, but the catch after the active throw or will cause the transaction rollback! (HI) then think of the initiative to throw new RuntimeException ("Feedback to the client Information"); The detailed error message that will be fed back to the client is wrapped in the exception message, and the exception occurs at the controller layer catch exception. Returns information to the client.
(MySQL table engine for innodb– support transaction rollback, default feel myisam– efficiency high)
To this, the problem is resolved.
Ii. Statement of Case
Post: Java service side
Work content: Receive request from client (android,androidtv,ios,pc.), validate client request data, and interact with other server to obtain data required by client.
Third, code and configuration 1.web.xml configuration
<?xml version="1.0" encoding="UTF-8"?
><listener><listener-class> org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value> </context-param> <servlet><servlet-name>spring-mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup> </servlet>
2. Spring-servlet.xml Configuration
<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:p= "http://www.springframework.org/schema/p" xmlns:context= "Http://www.springframework.org/schema/context" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:tx= " Http://www.springframework.org/schema/tx "xmlns:mvc=" Http://www.springframework.org/schema/mvc "xsi: schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans-3.0.xsd 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 Http://www.springframework.org/schema/mvc Http://www.springframewoRk.org/schema/mvc/spring-mvc-3.0.xsd "><!--Configure annotation scanning, scan controller layer does not scan service layer-<context: Component-scan base-package= "Cn.com.XX" > <context:include-filter type= "annotation" expression= "org . Springframework.stereotype.Controller "/> <context:exclude-filter type=" annotation "expression=" O Rg.springframework.stereotype.Service "/> </context:component-scan></beans>
3. Mybatis-config.xml Configuration
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <settings> <!-- changes from the defaults for testing --> <setting name="cacheEnabled" value="true" /> <setting name="useGeneratedKeys" value="true" /> <setting name="defaultExecutorType" value="REUSE" /> <!-- <setting name="logImpl" value="LOG4J"/> --> </settings> <!-- mybatis分页插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="mysql" /> </plugin> </plugins></configuration>
4. Applicationcontext.xml Configuration
<?xml version= "1.0" encoding= "UTF-8"?><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/ Xmlschema-instance "xmlns:p=" http://www.springframework.org/schema/p "xmlns:context="/HTTP/ Www.springframework.org/schema/context "xmlns:tx=" Http://www.springframework.org/schema/tx "xmlns:aop="/HTTP/ Www.springframework.org/schema/aop "xsi:schemalocation=" Http://www.springframework.org/schema/beans/http Www.springframework.org/schema/beans/spring-beans-3.0.xsd Http://www.springframework.org/schema/context/HTTP Www.springframework.org/schema/context/spring-context-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/TX/HTTP Www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aophttp:// Www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!--Load profile--<bean id=" Propertyconfigurer " class= "Org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > <property name= "locatio N "VAlue= "Classpath:system.properties"/> </bean> <!--configuration data source-<bean id= "DataSource" class= "COM.MC Hange.v2.c3p0.ComboPooledDataSource "> <property name=" driverclass "value=" Com.mysql.jdbc.Driver "> & lt;/property> <property name= "Jdbcurl" value= "${Database Connection}" > </property> <PR Operty name= "User" value= "root" ></property> <property name= "password" value= "root" ></property> <!--The maximum number of connections that are kept in the connection pool.
Default:15---<property name= "maxpoolsize" value= "></property> <!--the minimum number of connections left in the connection pool. --<property name= "Minpoolsize" value= "3" ></property> <!--the number of connections obtained at initialization, the value should be in Minpoolsize and MAXP Between the oolsize. Default:3---<property name= "Initialpoolsize" value= "3" ></property> <!--Max spare time, not used in 20 seconds The connection is discarded. If 0, it will never be discarded. default:0--<property name= "MaxIdleTime" value= "></property> <!--c3p0 once connections in the connection pool are exhausted The number of connections obtained at the same time. Default:3--<property name= "acquireincrement" > <value>5</value> </prop Erty> <!--the standard parameters for JDBC to control the number of preparedstatements loaded in the data source.
But because the pre-cached statements belong to a single connection instead of the entire connection pool. So there are a number of factors that need to be taken into account in setting this parameter. Assume that both the maxstatements and the maxstatementsperconnection are 0. The cache is closed.
default:0--<property name= "maxstatements" > <value>0</value> </propert Y> <!--Check the spare connections in all connection pools every 60 seconds. default:0--<property name= "Idleconnectiontestperiod" > <value>60</value> </property> <!--defines the number of times to try repeatedly after a new connection has failed to get from the database. Default:30--<property name= "acquireretryattempts" > <value>30</value> < ;/property> <!--getting a connection failure will cause the thread to wait for the connection pool to get the connection to throw an exception. The data source is still valid and continues to try to get the connection the next time you call Getconnection (). If set to True, the data source will declare broken and permanently shut down after attempting to acquire a connection failure. Default:false--<property name= "Breakafteracquirefailure" > <value>true</value> </property> <!--because of the high performance consumption, please use it only when you need it.
If set to true then the validity of each connection submission is officer. It is recommended to use methods such as Idleconnectiontestperiod or automatictesttable to improve the performance of the connection test.
Default:false--<property name= "Testconnectiononcheckout" > <value>true</value> </property> </bean> <!--annotation scan, not scan controller layer--<context:component-scan base-package= "cn.com.xx" > <context:exclude-filter type= "annotation" expression= " Org.springframework.stereotype.Controller "/> </context:component-scan> <bean id=" Sqlsessionfactory " class= "Org.mybatis.spring.SqlSessionFactoryBean" > <property name= "dataSource" ref= "DataSource"/> & Lt;property name= "configlocation" value= "Classpath:mybatis-config.xml"/> <property name= "mapperLocations" va Lue= "Classpath:cn/com/xx/**/*.xml"/> </bean> <!--yxt Add-to <bean id= "Mapperscanneryxt" Clas s= "Org.mybatis.spring.mapper.MapperScannerConfigurer" > <property name= "basepackage" value= "Cn.com.xx.mapper "/> </bean> <!--configuration transaction Manager--<!--transaction Manager, use Datasourcetransactionmanager---<bean id= "Txmanager" class= "Org.springframework.jdbc.dataso Urce. Datasourcetransactionmanager "> <property name=" dataSource "ref=" DataSource "/> </bean> <!-- Facets--<aop:config> <aop:pointcut id= "fooservicemethods" expression= "Execution (* cn.com. Xx.service.*.* (..)) " /> <aop:advisor advice-ref= "Txadvice" pointcut-ref= "Fooservicemethods"/> </aop:config> <!- -Notification-<tx:advice id= "Txadvice" transaction-manager= "Txmanager" > <tx:attributes> < Tx:method name= "select*" read-only= "true"/> <tx:method name= "*" rollback-for= "Exception"/> &L T;/tx:attributes> </tx:advice></beans>
5. Code Demo sample service business logic processing layer
try { log.info("check phone is exist before .."); int count = tMailingMapper.insert(record); if (count > 0) { log.info("加入 " + accountid + " 的好友" + account.getAccountid() + " " + phoneVo.getRemark() + " 成功"); } else { log.info("加入 " + accountid + " 的好友" + account.getAccountid() + " " + phoneVo.getRemark() + " 失败"); }} catch (Exception e) { log.error("加入联系人出现了异常 " + e.getMessage()); resJson.put("errorcode", "20022"); resJson.put("msg", "同步信息异常,请稍后重试"); throw new RuntimeException(resJson.toString());}
Controller control Layer
@RequestMapping("/update/userinfo") public String updateUserInfo(HttpServletRequest request, HttpServletResponse response) { log.info("update userInfo start .."); String resText=null; try { resText = userService.updateUserInfo(request); } catch (Exception e) { log.error("更新信息失败,事务已回滚...",e); resText=e.getMessage(); } <-- 将操作结果返回给client--> HttpsUtil.sendAppMessage(resText, response); return null; }
I first into the Java, Small white One, there is no place also please forgive me.
Welcome to the Great God guidance!
2016-03-19 10:58:58
Article: 1. http://sence-qi.iteye.com/blog/1328902/
2.http://blog.sina.com.cn/s/blog_89ca421401016bmg.html
SPRINGMVC MyBatis Declarative Transaction Management rollback invalidation, (checked rollback) catch exception, transmit error message