Springmvc+mybatis (when using Abstractroutingdatasource for multi-data source switching) a workaround for transaction management that does not take effect

Source: Internet
Author: User
Tags cdata

Business Scenario:

  A, b two units, the system deploys the same set of code;

A, b Two systems can access each other;

Request to synchronize data from a system to B system, and then send back the feedback information to A;

Actual development situation:

Because the system is relatively small, the initial design of the architecture did not take into account the way the message interworking, nor design a distributed deployment, so the use of Abstractroutingdatasource flexible data source to directly in the business code to achieve data interaction.

  

Project Code:

Applicationcontext-common.xml:

<?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:context= "Http://www.springframework.org/schema/context" Xmlns:util= "Http://www.springframework.org/schema/util" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:tx= "Http://www.springframework.org/schema/tx" xsi:schemalocation= "http://www.springframework.org/schema/ Beans Http://www.springframework.org/schema/beans/spring-beans.xsd Http://www.springframework.org/schema/context Http://www.springframework.org/schema/context/spring-context-4.1.xsd Http://www.springframework.org/schema/util Http://www.springframework.org/schema/util/spring-util-4.1.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP/HTTP Www.springframework.org/schema/aop/spring-aop.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/TX/HTTP Www.springframework.org/schema/tx/spring-tx-4.1.xsd "> <context:component-scan Base-pacKage= "COM.FMS;COM.JOB;COM.JMDA;" > <context:exclude-filter type= "regex" expression= ". controller.*"/> </context:component-scan>< Bean id= "Freemarkerconfig" class= "Org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" >< Property Name= "Templateloaderpaths" ><list><value>/web-inf/pages/</value><value>/ Web-inf/template/</value><value>classpath:/jmda-ftl/</value></list></property> <property name= "freemarkersettings" ><props><prop key= "Template_update_delay" >0</prop> <prop key= "default_encoding" >utf-8</prop><prop key= "Number_format" >0.##########</prop> <prop key= "Datetime_format" >yyyy-mm-dd hh:mm:ss</prop><prop key= "classic_compatible" >true</ Prop><prop key= "Template_exception_handler" >ignore</prop></props></property></ bean><!--Configuring the C3P0 data source--><bean id= "DataSource1" class= "com.mchange.v2.c3p0.combopooleddatasource "destroy-method=" Close "><property name=" Jdbcurl "><value><! [cdata[jdbc:mysql://192.168.5.186:3306/fms-ybj?useunicode=yes&characterencoding=utf8]]></value> </property><property name= "Driverclass" value= "Com.mysql.jdbc.Driver"/><property name= "user" value= "Root"/><property name= "password" value= "root"/><property name= "Maxpoolsize" value= "$"/>< Property Name= "Minpoolsize" value= "1"/><property name= "Initialpoolsize" value= "1"/><property name= " MaxIdleTime "value=" "/><property name=" Acquireincrement "value=" 5 "/><property name=" MaxStatements " Value= "0"/><property name= "Idleconnectiontestperiod" value= "/><property name=" acquireRetryAttempts "Value=" "/><property name=" Breakafteracquirefailure "value=" true "/><property name=" Testconnectiononcheckout "value=" false "/></bean><bean id=" DataSource2 "class=" Com.mchange.v2.c3p0.ComboPoolEddatasource "destroy-method=" Close "><property name=" Jdbcurl "> <value><! [cdata[jdbc:mysql://192.168.5.186:3306/fms-zhs?useunicode=yes&characterencoding=utf8]]></value> </property><property name= "Driverclass" value= "Com.mysql.jdbc.Driver"/><property name= "user" value= "Root"/><property name= "password" value= "root"/><property name= "Maxpoolsize" value= "$"/>< Property Name= "Minpoolsize" value= "1"/><property name= "Initialpoolsize" value= "1"/><property name= " MaxIdleTime "value=" "/><property name=" Acquireincrement "value=" 5 "/><property name=" MaxStatements " Value= "0"/><property name= "Idleconnectiontestperiod" value= "/><property name=" acquireRetryAttempts "Value=" "/><property name=" Breakafteracquirefailure "value=" true "/><property name=" Testconnectiononcheckout "value=" false "/></bean> <bean id=" Multipledatasource "class=" Com.fms.common.datasource.MuLtipledatasource "> <property name=" defaulttargetdatasource "ref=" DataSource1 "/> <property na Me= "Targetdatasources" > <map> <entry key= "DataSource1" value-ref= "DataSource1"/&                  Gt <entry key= "DataSource2" value-ref= "DataSource2"/> </map> </property> </be An><bean id= "Msqlsessionfactory" class= "Org.mybatis.spring.SqlSessionFactoryBean" ><property name= " DataSource "ref=" Multipledatasource "/><property name=" configlocation "value=" Classpath:mybatis.xml "/> <property name= "Mapperlocations" ><list><value>classpath*:/com/fms/**/dao/*mapper.xml</ Value><value>classpath*:/com/fms/**/dao/*dao.xml</value></list></property></bean ><bean class= "Org.mybatis.spring.mapper.MapperScannerConfigurer" ><property name= "Basepackage" value= " Com.fms.**.dao "/><property name=" sqlsessionfactory "ref= "Msqlsessionfactory"/></bean><bean id= "TransactionManager" class= " Org.springframework.jdbc.datasource.DataSourceTransactionManager "><property name=" datasource "ref=" Multipledatasource "/></bean>
<tx:annotation-driven transaction-manager= "TransactionManager"/>
<!--file Upload configuration-<bean id= "Multipartresolver" class= "Org.springframework.web.multipart.commons.CommonsM Ultipartresolver "> <property name=" maxuploadsize "value=" 10240000 "/> <property name=" maxInMemorySize "Value=" 10240000 "/></bean> </beans>

  

Springmvc-servlet.xml:

<?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:aop= "Http://www.springframework.org/schema/aop" xmlns: Cache= "Http://www.springframework.org/schema/cache" xmlns:context= "http://www.springframework.org/schema/ Context "xmlns:jdbc=" Http://www.springframework.org/schema/jdbc "xmlns:jee=" http://www.springframework.org/ Schema/jee "xmlns:jms=" HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/JMS "xmlns:lang=" http://www.springframework.org/ Schema/lang "xmlns:mvc=" Http://www.springframework.org/schema/mvc "xmlns:oxm=" http://www.springframework.org/ SCHEMA/OXM "xmlns:p=" http://www.springframework.org/schema/p "xmlns:task=" http://www.springframework.org/schema/ Task "xmlns:tx=" Http://www.springframework.org/schema/tx "xmlns:mongo=" http://www.springframework.org/schema/ Data/mongo "xmlns:util=" Http://www.springframework.org/schema/util "xmlns:ehcache="/HTTP/ Ehcache-spring-annotations.googlecode.com/svn/schEma/ehcache-spring "xsi:schemalocation=" Http://www.springframework.org/schema/beans/http Www.springframework.org/schema/beans/spring-beans.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP Http://www.spri Ngframework.org/schema/aop/spring-aop-4.1.xsd Http://www.springframework.org/schema/cache Http://www.springfram Ework.org/schema/cache/spring-cache-4.1.xsd Http://www.springframework.org/schema/context Http://www.springfram Ework.org/schema/context/spring-context-4.1.xsd Http://www.springframework.org/schema/jdbc Http://www.springfra Mework.org/schema/jdbc/spring-jdbc-4.1.xsd Http://www.springframework.org/schema/jee Http://www.springframework . org/schema/jee/spring-jee-4.1.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/JMS Http://www.springframework.org/sch Ema/jms/spring-jms-4.1.xsd Http://www.springframework.org/schema/lang Http://www.springframework.org/schema/lan G/spring-lang-4.1.xsd Http://www.springframewORK.ORG/SCHEMA/MVC http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/ SCHEMA/OXM http://www.springframework.org/schema/oxm/spring-oxm-4.1.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/T Ask Http://www.springframework.org/schema/task/spring-task-4.1.xsd http://www.springframework.org/schema/tx htt P://www.springframework.org/schema/tx/spring-tx-4.1.xsd Http://www.springframework.org/schema/util/HTTP Www.springframework.org/schema/util/spring-util-4.1.xsd "> <context:component-scan base-package=" COM.FMS;       Com.job;com.jmda; "/>
<mvc:annotation-driven><mvc:message-converters><bean class= " Org.springframework.http.converter.StringHttpMessageConverter "><property name=" Supportedmediatypes "> <list> <value>text/plain;charset=utf-8</value><value>text/html;charset=utf-8</value ></list></property></bean></mvc:message-converters></mvc:annotation-driven> <bean id= "Viewresolver" class= "Org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" > <property name= "Cache" value= "true"/> <property name= "suffix" value= ". Ftl"/> <property na Me= "ContentType" value= "Text/html;charset=utf-8" ></property> <property name= "Requestcontextattribute" value= "Request"/> <property name= "Exposespringmacrohelpers" value= "true"/> <property name= "exp Oserequestattributes "value=" true "/> <property name=" exposesessionattributes "value=" true "/&GT </bean><mvc:resources mapping= "/static/**" location= "/static/"/><mvc:resources mapping= "/ jmda-static/** "location="/jmda-static/"/><mvc:resources mapping="/assets/** "location="/assets/"/>< mvc:interceptors> <bean class= "Com.fms.common.listener.SecurityInterceptor"/> </mvc:interceptors> </beans>

Web. xml:

<?xml version= "1.0" encoding= "UTF-8"? ><web-app metadata-complete= "true" xmlns:xsi= "http://www.w3.org/2001 /xmlschema-instance "xmlns=" Http://java.sun.com/xml/ns/javaee "xmlns:web=" http://java.sun.com/xml/ns/javaee/ Web-app_2_5.xsd "xsi:schemalocation=" Http://java.sun.com/xml/ns/javaee Http://java.sun.com/xml/ns/javaee/web-app _2_5.xsd "version=" 2.5 "><context-param><param-name>contextConfigLocation</param-name>< param-value>classpath*:/spring/applicationcontext*.xml</param-value></context-param>< Listener><listener-class>org.springframework.web.context.contextloaderlistener</listener-class> </listener><listener><listener-class> Org.springframework.web.util.introspectorcleanuplistener</listener-class></listener><filter> <filter-name>CharacterEncodingFilter</filter-name><filter-class> org.springframework.web.filter.characterencodingfilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></ Filter><filter-mapping><filter-name>characterencodingfilter</filter-name><url-pattern >/*</url-pattern></filter-mapping><servlet><servlet-name>spring4mvc</ Servlet-name><servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> <init-param><param-name>contextconfiglocation</param-name><param-value>classpath*:/ spring/springmvc-servlet.xml</param-value></init-param><load-on-startup>1</ Load-on-startup></servlet><servlet-mapping><servlet-name>spring4mvc</servlet-name> <url-pattern>/</url-pattern></servlet-mapping><context-param><param-name> Log4jconfiglocation</param-name><param-value>/web-inf/classes/log4j.properties</param-value> </context-param><listener><listener-class>org.springframework.web.util.log4jconfiglistener</listener-class></listener> <listener > <listener-class>com.fms.common.listener.CommListener</listener-class> </listener><!-- 400 error--><error-page><error-code>400</error-code><location>/error</location> </error-page><!--404 page does not exist error--><error-page><error-code>404</error-code>< location>/error</location></error-page><!--403 server denied request--><error-page><error-code >403</error-code><location>/error</location></error-page><!--500 Server Internal Error-- <error-page><error-code>500</error-code><location>/error</location></ error-page><!--503 Service Unavailable--><error-page><error-code>503</error-code><location>/ error</location></error-page><!--java.lang.Exception--><error-page><exception-type>java.lang.exception</exception-type><location>/error</location></error-page><!- -Java.lang.NullPointerException--><error-page><exception-type>java.lang.nullpointerexception </exception-type><location>/error</location></error-page><error-page>< Exception-type>javax.servlet.servletexception</exception-type><location>/error</location> </error-page><welcome-file-list><welcome-file></welcome-file></welcome-file-list ></web-app>

  

Multipledatasource:

Package Com.fms.common.datasource;import Org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class Multipledatasource extends Abstractroutingdatasource {    private static final threadlocal<string> Datasourcekey = new inheritablethreadlocal<string> ();    public static void Setdatasourcekey (String dataSource) {        datasourcekey.remove ();    }        public static void Setdatasource (String dataSource) {    datasourcekey.remove ();    Datasourcekey.set (DataSource);    }    public static String GetKey () {    return datasourcekey.get ();    }    @Override    protected Object Determinecurrentlookupkey () {        return datasourcekey.get ();}    }

  

A brief business code

        @Transactional (rollbackfor = {exception.class}) @Overridepublic void Test () {///default data source is datasource1//do some SQL operate// Switch data source Multipledatasource.setdatasource ("Datasource2");//do other SQL operate//...}.    

  

Code to the above stage, the business under normal conditions can be executed smoothly, but in the event of an exception when the transaction can not be rolled back, so I find various methods on the Internet to try to modify;

At first, I thought it was abstractroutingdatasource. Multi-data source problem, has been from this aspect to find the answer, find a lot of examples of changes are still unable to open the transaction management, occasionally saw a post on the spring father and son container configuration, after reading after the change, Then restart the project and the results are really successful.

The specific changes are as follows:

In Applicationcontext-common.xml:

<!--  <context:component-scan base-package= "COM.FMS;COM.JOB;COM.JMDA;" >        <context:exclude-filter type= "regex" expression= ". controller.*"/>    </context:component-scan >--> changed to:    <context:component-scan base-package= "COM.FMS;COM.JOB;COM.JMDA;" >        <context:exclude-filter type= "annotation" expression= "Org.springframework.stereotype.Controller"/ >    </context:component-scan>

In Springmvc-servlet.xml:

<!--<context:component-scan base-package= "COM.FMS;COM.JOB;COM.JMDA;"/>--> instead:    <context: Component-scan base-package= "COM.FMS;COM.JOB;COM.JMDA;" >          <context:exclude-filter type= "annotation" expression= "Org.springframework.stereotype.Service"/>    </context:component-scan>

Reason:

The spring container first loads the parent container generated by Servletcontextlistener (corresponding applicationcontext.xml), and SPRINGMVC (corresponding Mvc_dispatcher_ Servlet.xml) produces a sub-container. The instance of the @service annotation assembled when the sub-container controller is scanned for assembly is not transacted, that is, a service with no transaction capability, and the service that the parent container initializes is a guarantee of the transaction's enhanced processing power. If the service is not exclude in the sub-container, it will be provided as-is service without transaction capability, because in multi-context case, if the same bean is defined two times, the next one takes precedence.

---------Note: This paragraph is excerpted from: http://blog.csdn.net/will_awoke/article/details/12002705

Springmvc+mybatis (when using Abstractroutingdatasource for multi-data source switching) a workaround for transaction management that does not take effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.