国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用spring+hibernate+atomikos+tomcat構建分布式事務

2019-11-14 23:08:07
字體:
來源:轉載
供稿:網友
使用sPRing+hibernate+atomikos+tomcat構建分布式事務

本文通過一個demo,介紹如何使用spring+hibernate+atomikos+tomcat構建在一個事務中涉及兩個數據源的web應用。

demo功能:實現一個能成功提交和回滾的涉及兩個數據庫數據源的XA事務。

demo將實現:

1.一次性在兩個數據庫的兩張表中各插入一條數據并提交。

2.一次性在兩個數據庫的兩張表中各插入一條數據并回滾。

測試方式:restful web api

使用工具:

spring4.1.1.RELEASE

hibernate4.2.4.Final

atomikos 3.7.0

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 table

代碼分析:

本項目使用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  17  18     <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" 19           destroy-method="close" abstract="true"> 20         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> 21         <property name="poolSize" value="10" /> 22         <property name="minPoolSize" value="10"/> 23         <property name="maxPoolSize" value="30"/> 24         <property name="borrowConnectionTimeout" value="60"/> 25         <property name="reapTimeout" value="20"/> 26         <!-- 最大空閑時間 --> 27         <property name="maxIdleTime" value="60"/> 28         <property name="maintenanceInterval" value="60"/> 29         <property name="loginTimeout" value="60"/> 30         <property name="testQuery"> 31             <value>select 1</value> 32         </property> 33     </bean> 34  35     <bean id="qadataSource" parent="abstractXADataSource"> 36         <!-- value只要兩個數據源不同就行,隨便取名 --> 37         <property name="uniqueResourceName" value="mysql/sitestone" /> 38         <property name="xaDataSourceClassName" 39                   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> 40         <property name="xaProperties"> 41             <props> 42                 <prop key="URL">${qa.db.url}</prop> 43                 <prop key="user">${qa.db.user}</prop> 44                 <prop key="passWord">${qa.db.password}</prop> 45                 <prop key="pinGlobalTxToPhysicalConnection">true</prop> 46             </props> 47         </property> 48     </bean> 49  50     <bean id="devdataSource" parent="abstractXADataSource"> 51         <!-- value只要兩個數據源不同就行,隨便取名 --> 52         <property name="uniqueResourceName" value="mysql/sitestone1" /> 53         <property name="xaDataSourceClassName" 54                   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> 55         <property name="xaProperties"> 56             <props> 57                 <prop key="URL">${dev.db.url}</prop> 58                 <prop key="user">${dev.db.user}</prop> 59                 <prop key="password">${dev.db.password}</prop> 60                 <prop key="pinGlobalTxToPhysicalConnection">true</prop> 61             </props> 62         </property> 63     </bean> 64  65     <bean id="qasessionFactory" 66                  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 67         <property name="packagesToScan" value="com.xy.model"/> 68         <property name="dataSource" ref="qadataSource"/> 69         <property name="hibernateProperties"> 70             <props> 71                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> 72                 <prop key="hibernate.show_sql">false</prop> 73                 <prop key="hibernate.autoReconnect">true</prop> 74                 <prop key="hibernate.connection.release_mode">after_transaction</prop> 75             </props> 76         </property> 77     </bean> 78     <bean id="devSessionFactory" 79           class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 80         <property name="packagesToScan" value="com.xy.model"/> 81         <property name="dataSource" ref="devdataSource"/> 82         <property name="hibernateProperties"> 83             <props> 84                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> 85                 <prop key="hibernate.show_sql">false</prop> 86                 <prop key="hibernate.autoReconnect">true</prop> 87                 <prop key="hibernate.connection.release_mode">after_transaction</prop> 88             </props> 89         </property> 90     </bean> 91  92     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 93           init-method="init" destroy-method="close"> 94         <property name="forceShutdown"> 95             <value>true</value> 96         </property> 97     </bean> 98     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> 99         <property name="transactionTimeout" value="300" />100     </bean>101 102     <bean id="transactionManager"103           class="org.springframework.transaction.jta.JtaTransactionManager">104         <property name="transactionManager">105             <ref bean="atomikosTransactionManager"/>106         </property>107         <property name="userTransaction">108             <ref bean="atomikosUserTransaction"/>109         </property>110         <!-- 必須設置,否則程序出現異常 JtaTransactionManager does not support custom isolation levels by default -->111         <property name="allowCustomIsolationLevels" value="true"/>112 113     </bean>114 115 </beans>

其中qadataSource和devdataSource是對應兩個數據庫的數據源,qaSessionFactory和devSessionFactory是hibernate的sessionfactory。atomikosTransactionManager會自動管理兩個atomikos的數據源的事務,即resource manager,atomikosUserTransaction為最上層的事務管理器為transaction manager。(關于RM和TM,請參見上篇博文)。

Model類如下:package com.xy.model

package com.xy.model;import javax.persistence.*;/** * Created by helloworld on 2015/1/30. */@Entity@Table(name = "nameDev")public class NameDev {    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    private long id;    private String nameDev;    public long getId() {        return id;    }    public void setId(long id) {        this.id = id;    }    public String getNameDev() {        return nameDev;    }    public void setNameDev(String nameDev) {        this.nameDev = nameDev;    }}
NameDev
 1 package com.xy.model; 2  3  4 import javax.persistence.*; 5  6 /** 7  * Created by helloworld on 2015/1/30. 8  */ 9 @Entity10 @Table(name = "nameQa")11 public class NameQa {12     @Id13     @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 @Service14 public class NameService {15     @Autowired16     private SessionFactory qaSessionFactory;17     @Autowired18     private SessionFactory devSessionFactory;19 20     @Transactional(rollbackFor = Exception.class)21     public void addQaAndDev(boolean hasException) throws Exception {22         NameQa nameQa = new NameQa();23         nameQa.setNameQa("hello");24         qaSessionFactory.getCurrentSession().save(nameQa);25 26         NameDev nameDev = new NameDev();27         nameDev.setNameDev("hello");28         devSessionFactory.getCurrentSession().save(nameDev);29 30         if(hasException){31             throw new Exception();32         }33 34     }35 36 37 }
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 @Controller16 public class hibernateController {17     @Autowired18     NameService nameService;19 20 21     @RequestMapping(value = "/addName", method = RequestMethod.POST)22     ModelMap addName(@RequestParam("hasException") boolean hasException){23         try {24             nameService.addQaAndDev(hasException);25         } catch (Exception e) {26             e.printStackTrace();27             return new ModelMap("false");28         }29         return new ModelMap("true");30     }31 32 33 }
controller

將項目打成war包,命名為test.war部署在tomcat上。

測試:

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

request parameters: hasException=false返回:true 數據添加成功

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

 request parameters: hasException=true

返回:false 兩個數據庫數據都未添加源碼下載:http://files.VEVb.com/files/rain-in-sun/springmvc-hibernate-atomikos.rar

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 夏河县| 奉节县| 印江| 清镇市| 黄平县| 融水| 乌兰县| 图木舒克市| 秦安县| 澄江县| 沧州市| 弋阳县| 会东县| SHOW| 盱眙县| 平乐县| 佛坪县| 龙门县| 岑溪市| 突泉县| 镇平县| 海城市| 深泽县| 隆安县| 大城县| 如皋市| 广水市| 称多县| 九龙城区| 左云县| 沁源县| 西贡区| 广东省| 南溪县| 来宾市| 翁牛特旗| 进贤县| 原平市| 苏尼特右旗| 乳山市| 旬阳县|