码迷,mamicode.com
首页 > 编程语言 > 详细

spring+hibernate管理多个数据源(非分布式事务)

时间:2015-03-05 00:07:16      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

本文通过一个demo,介绍如何使用spring+hibernate管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务。

这个demo将使用两个事务管理器分别管理两个数据源。对于每一个独立的事务,只涉及一个数据源。

demo功能:实现一个能依靠两个独立的事务管理器互不干涉的管理自己的数据源的web demo。

demo将实现:

1.独立地控制两个不同的数据源的事务管理器。

 

测试方式:restful web api

 

使用工具:

spring 4.1.1.RELEASE

hibernate 4.2.4.Final

tomcat 7

 

在mysql中建立两个schema,分别为dev和qa。并在里面分别建立一张名字表。

schema:dev

table:namaDev

id | nameDev

 

scheme:qa

table:nameQa

id  |  nameQa

对应的sql为

技术分享
 1 CREATE SCHEMA `qa` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
 2 CREATE SCHEMA `dev` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
 3 
 4  CREATE  TABLE `dev`.`nameDev` (
 5   `id` BIGINT NOT NULL AUTO_INCREMENT ,
 6   `nameDev` VARCHAR(45) NULL ,
 7   PRIMARY KEY (`id`) ,
 8   UNIQUE INDEX `id_UNIQUE` (`id` ASC) );
 9 
10   CREATE  TABLE `qa`.`nameQa` (
11   `id` BIGINT NOT NULL AUTO_INCREMENT ,
12   `nameQa` VARCHAR(45) NULL ,
13   PRIMARY KEY (`id`) ,
14   UNIQUE INDEX `id_UNIQUE` (`id` ASC) );
create sql

代码分析:

本项目使用spring框架,因此首先配置相关bean

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3        xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
 4        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 5        xmlns:rabbit="http://www.springframework.org/schema/rabbit"
 6        xmlns:cache="http://www.springframework.org/schema/cache" xmlns:task="http://www.springframework.org/schema/task"
 7        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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
 8        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
 9     <context:property-placeholder file-encoding="UTF-8" ignore-resource-not-found="true"
10                                   location="classpath*:context/database.properties"/>
11     <context:component-scan base-package="com.xy">
12         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
13     </context:component-scan>
14     <tx:annotation-driven/>
15 
16     <bean id="qadataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
17           destroy-method="close">
18         <property name="jdbcUrl" value="${qa.db.url}"></property>
19         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
20         <property name="user" value="${qa.db.user}"></property>
21         <property name="password" value="${qa.db.password}"></property>
22         <property name="maxPoolSize" value="20"></property>
23         <property name="minPoolSize" value="20"></property>
24         <property name="initialPoolSize" value="20"></property>
25         <property name="maxIdleTime" value="200"></property>
26         <!--<property name="numHelperThreads" value="50"></property>-->
27     </bean>
28 
29     <!--<bean id="qadataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">-->
30         <!--<property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
31         <!--<property name="url" value="${qa.db.url}"/>-->
32         <!--<property name="username" value="${qa.db.user}"/>-->
33         <!--<property name="password" value="${qa.db.password}"/>-->
34     <!--</bean>-->
35 
36     <!--<bean id="devdataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">-->
37         <!--<property name="driverClassName" value="com.mysql.jdbc.Driver"/>-->
38         <!--<property name="url" value="${dev.db.url}"/>-->
39         <!--<property name="username" value="${dev.db.user}"/>-->
40         <!--<property name="password" value="${dev.db.password}"/>-->
41     <!--</bean>-->
42 
43     <bean id="devdataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
44           destroy-method="close">
45         <property name="jdbcUrl" value="${dev.db.url}"></property>
46         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
47         <property name="user" value="${dev.db.user}"></property>
48         <property name="password" value="${dev.db.password}"></property>
49         <property name="maxPoolSize" value="20"></property>
50         <property name="minPoolSize" value="20"></property>
51         <property name="initialPoolSize" value="20"></property>
52         <property name="maxIdleTime" value="200"></property>
53         <!--<property name="numHelperThreads" value="50"></property>-->
54     </bean>
55 
56 
57     <bean id="qaSessionFactory"
58                  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
59         <property name="packagesToScan" value="com.xy.model"/>
60         <property name="dataSource" ref="qadataSource"/>
61         <property name="hibernateProperties">
62             <props>
63                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
64                 <prop key="hibernate.show_sql">false</prop>
65                 <prop key="hibernate.autoReconnect">true</prop>
66                 <prop key="hibernate.connection.release_mode">after_transaction</prop>
67             </props>
68         </property>
69     </bean>
70 
71     <bean id="devSessionFactory"
72           class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
73         <property name="packagesToScan" value="com.xy.model"/>
74         <property name="dataSource" ref="devdataSource"/>
75         <property name="hibernateProperties">
76             <props>
77                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
78                 <prop key="hibernate.show_sql">false</prop>
79                 <prop key="hibernate.autoReconnect">true</prop>
80                 <prop key="hibernate.connection.release_mode">after_transaction</prop>
81             </props>
82         </property>
83     </bean>
84 
85     <bean id="qaManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
86         <property name="sessionFactory" ref="qaSessionFactory" />
87     </bean>
88 
89     <bean id="devManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
90         <property name="sessionFactory" ref="devSessionFactory" />
91     </bean>
92 
93 </beans>
bean配置

其中qadataSource和devdataSource是对应两个数据库的数据源,qaSessionFactory和devSessionFactory是hibernate的sessionfactory。qaManager与devManage分别管理qadataSource和devdataSource的事务,互不干涉。注意事务管理器必须是hibernate4的类型。

Model类如下:package com.xy.model

技术分享
 1 package com.xy.model;
 2 
 3 
 4 import javax.persistence.*;
 5 
 6 /**
 7  * Created by helloworld on 2015/1/30.
 8  */
 9 @Entity
10 @Table(name = "nameDev")
11 public class NameDev {
12     @Id
13     @GeneratedValue(strategy = GenerationType.AUTO)
14     private long id;
15     private String nameDev;
16 
17     public long getId() {
18         return id;
19     }
20 
21     public void setId(long id) {
22         this.id = id;
23     }
24 
25     public String getNameDev() {
26         return nameDev;
27     }
28 
29     public void setNameDev(String nameDev) {
30         this.nameDev = nameDev;
31     }
32 }
NameDev
技术分享
 1 package com.xy.model;
 2 
 3 
 4 import javax.persistence.*;
 5 
 6 /**
 7  * Created by helloworld on 2015/1/30.
 8  */
 9 @Entity
10 @Table(name = "nameQa")
11 public class NameQa {
12     @Id
13     @GeneratedValue(strategy = GenerationType.AUTO)
14     private long id;
15     private String nameQa;
16 
17     public long getId() {
18         return id;
19     }
20 
21     public void setId(long id) {
22         this.id = id;
23     }
24 
25     public String getNameQa() {
26         return nameQa;
27     }
28 
29     public void setNameQa(String nameQa) {
30         this.nameQa = nameQa;
31     }
32 }
NameQa

处理事务的service

技术分享
 1 package com.xy.service;
 2 
 3 import com.xy.model.NameDev;
 4 import com.xy.model.NameQa;
 5 import org.hibernate.SessionFactory;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.stereotype.Service;
 8 import org.springframework.transaction.annotation.Transactional;
 9 
10 /**
11  * Created by helloworld on 2015/1/30.
12  */
13 @Service
14 public class NameService {
15     @Autowired
16     private SessionFactory qaSessionFactory;
17     @Autowired
18     private SessionFactory devSessionFactory;
19 
20     @Transactional(value = "qaManager",rollbackFor = Exception.class)
21     public void addQa(boolean hasQaException) throws Exception {
22         NameQa nameQa = new NameQa();
23         nameQa.setNameQa("hello");
24         qaSessionFactory.getCurrentSession().save(nameQa);
25 
26         if(hasQaException){
27             throw new Exception();
28         }
29     }
30 
31     @Transactional(value = "devManager", rollbackFor = Exception.class)
32     public void addDev(boolean hasDevQaException) throws Exception {
33         NameDev nameDev = new NameDev();
34         nameDev.setNameDev("hello");
35         devSessionFactory.getCurrentSession().save(nameDev);
36 
37         if(hasDevQaException){
38             throw new Exception();
39         }
40     }
41 
42 }
service

controller代码

技术分享
 1 package com.xy.controller;
 2 
 3 import com.xy.service.NameService;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.stereotype.Controller;
 6 import org.springframework.ui.ModelMap;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.RequestMethod;
 9 import org.springframework.web.bind.annotation.RequestParam;
10 
11 
12 /**
13  * Created by helloworld on 2014/11/22.
14  */
15 @Controller
16 public class hibernateController {
17     @Autowired
18     NameService nameService;
19 
20 
21     @RequestMapping(value = "/addName", method = RequestMethod.POST)
22     ModelMap addName(@RequestParam("hasQaException") boolean hasQaException,
23                      @RequestParam("hasDevException") boolean hasDevException){
24         try {
25             nameService.addQa(hasQaException);
26         } catch (Exception e) {
27             e.printStackTrace();
28         }
29 
30         try {
31             nameService.addDev(hasDevException);
32         } catch (Exception e) {
33             e.printStackTrace();
34         }
35         return new ModelMap("true");
36     }
37 
38 
39 }
controller

将项目打成war包,命名为test.war部署在tomcat上。

测试:

1.POST  http://localhost:8080/test/addName.json

request parameters:
withDevException=false
witQaException=false
返回:true 两个数据都添加成功

2.POST  http://localhost:8080/test/addName.json

request parameters:
withDevException=false
witQaException=true
返回:true 只有dev添加成功
源码下载:http://files.cnblogs.com/files/rain-in-sun/springmvc-hibernate-multidatasource.rar

 

spring+hibernate管理多个数据源(非分布式事务)

标签:

原文地址:http://www.cnblogs.com/rain-in-sun/p/4314534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!