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

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

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

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

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

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

demo將實現:

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

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

測試方式:restful web api

使用工具:

spring4.1.1.RELEASE

mybatis 3.2.7

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) );

代碼分析:

本項目使用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:component-scan base-package="com.xy"> 10         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 11     </context:component-scan> 12     <context:property-placeholder location="classpath:context/database.properties"/> 13     <tx:annotation-driven/> 14  15     <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" 16           destroy-method="close" abstract="true"> 17         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> 18         <property name="poolSize" value="10" /> 19         <property name="minPoolSize" value="10"/> 20         <property name="maxPoolSize" value="30"/> 21         <property name="borrowConnectionTimeout" value="60"/> 22         <property name="reapTimeout" value="20"/> 23         <!-- 最大空閑時間 --> 24         <property name="maxIdleTime" value="60"/> 25         <property name="maintenanceInterval" value="60"/> 26         <property name="loginTimeout" value="60"/> 27         <property name="testQuery"> 28             <value>select 1</value> 29         </property> 30     </bean> 31      32     <bean id="qadataSource" parent="abstractXADataSource"> 33         <!-- value只要兩個數據源不同就行,隨便取名 --> 34         <property name="uniqueResourceName" value="mysql/sitestone1" /> 35         <property name="xaDataSourceClassName" 36                   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> 37         <property name="xaProperties"> 38             <props> 39                 <prop key="URL">${qa.db.url}</prop> 40                 <prop key="user">${qa.db.user}</prop> 41                 <prop key="passWord">${qa.db.password}</prop> 42                 <prop key="pinGlobalTxToPhysicalConnection">true</prop> 43             </props> 44         </property> 45     </bean> 46  47     <bean id="devdataSource" parent="abstractXADataSource"> 48         <!-- value只要兩個數據源不同就行,隨便取名 --> 49         <property name="uniqueResourceName" value="mysql/sitestone" /> 50         <property name="xaDataSourceClassName" 51                   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> 52         <property name="xaProperties"> 53             <props> 54                 <prop key="URL">${dev.db.url}</prop> 55                 <prop key="user">${dev.db.user}</prop> 56                 <prop key="password">${dev.db.password}</prop> 57                 <prop key="pinGlobalTxToPhysicalConnection">true</prop> 58             </props> 59         </property> 60     </bean> 61  62  63  64     <bean id="qasqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 65         <property name="dataSource" ref="qadataSource" /> 66         <property name="mapperLocations" value="classpath*:com/xy/dao/*.xml" /> 67     </bean> 68  69     <bean id="devsqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 70         <property name="dataSource" ref="devdataSource" /> 71         <property name="mapperLocations" value="classpath*:com/xy/daodev/*.xml" /> 72     </bean> 73  74     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 75           init-method="init" destroy-method="close"> 76         <property name="forceShutdown"> 77             <value>true</value> 78         </property> 79     </bean> 80     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> 81         <property name="transactionTimeout" value="300" /> 82     </bean> 83  84     <bean id="transactionManager" 85           class="org.springframework.transaction.jta.JtaTransactionManager"> 86         <property name="transactionManager"> 87             <ref bean="atomikosTransactionManager"/> 88         </property> 89         <property name="userTransaction"> 90             <ref bean="atomikosUserTransaction"/> 91         </property> 92         <!-- 必須設置,否則程序出現異常 JtaTransactionManager does not support custom isolation levels by default --> 93         <property name="allowCustomIsolationLevels" value="true"/> 94  95     </bean> 96  97  98  99     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">100         <property name="basePackage" value="com.xy.dao"/>101         <property name="sqlSessionFactoryBeanName" value="qasqlSessionFactory" />102     </bean>103 104     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">105         <property name="basePackage" value="com.xy.daodev"/>106         <property name="sqlSessionFactoryBeanName" value="devsqlSessionFactory" />107     </bean>108 </beans>

其中qadataSource和devdataSource是對應兩個數據庫的數據源,qasqlSessionFactory和devsqlSessionFactory是mybatis的sessionfactory,兩個MapperScannerConfigurer自動將不同數據源的sql語句文件與interface自動裝配起來,atomikosTransactionManager會自動管理兩個atomikos的數據源的事務,即resource manager,atomikosUserTransaction為最上層的事務管理器為transaction manager。(關于RM和TM,請參見上篇博文)。

Model類如下:package com.xy.model

 1 package com.xy.model; 2  3 /** 4  * Created by helloworld on 2015/1/30. 5  */ 6 public class NameQa { 7     private long id; 8     private String nameQa; 9 10     public long getId() {11         return id;12     }13 14     public void setId(long id) {15         this.id = id;16     }17 18     public String getNameQa() {19         return nameQa;20     }21 22     public void setNameQa(String nameQa) {23         this.nameQa = nameQa;24     }25 }
nameQa class

 1 package com.xy.model; 2  3 /** 4  * Created by helloworld on 2015/1/30. 5  */ 6 public class NameDev { 7     private long id; 8     private String nameDev; 9 10     public long getId() {11         return id;12     }13 14     public void setId(long id) {15         this.id = id;16     }17 18     public String getNameDev() {19         return nameDev;20     }21 22     public void setNameDev(String nameDev) {23         this.nameDev = nameDev;24     }25 }
nameDev class

qa數據源的mybatis mapper接口 package com.xy.dao

 1 package com.xy.dao; 2  3 import com.xy.model.NameQa; 4  5 /** 6  * Created by helloworld on 2015/1/30. 7  */ 8 public interface NameQaMapper { 9     int insert(NameQa nameQa);10 }
NameQaMapper

dev數據源的mybatis mapper接口 package com.xy.devdao

 1 package com.xy.daodev; 2  3 import com.xy.model.NameDev; 4  5 /** 6  * Created by helloworld on 2015/1/30. 7  */ 8 public interface NameDevMapper { 9     int insert(NameDev nameDev);10 }
NameDevMapper

處理事務的service

 1 package com.xy.service; 2  3 import com.xy.dao.NameQaMapper; 4 import com.xy.daodev.NameDevMapper; 5 import com.xy.model.NameDev; 6 import com.xy.model.NameQa; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.stereotype.Service; 9 import org.springframework.transaction.annotation.Transactional;10 11 /**12  * Created by helloworld on 2015/1/30.13  */14 @Service15 public class NameService {16     @Autowired17     NameQaMapper nameQaMapper;18     @Autowired19     NameDevMapper nameDevMapper;20 21     @Transactional(rollbackFor = Exception.class)22     public void addQaAndDev(boolean hasException) throws Exception {23         NameQa nameQa = new NameQa();24         nameQa.setNameQa("qa");25         nameQaMapper.insert(nameQa);26 27         NameDev nameDev = new NameDev();28         nameDev.setNameDev("dev");29         nameDevMapper.insert(nameDev);30 31         if(hasException) {32             throw new Exception();33         }34     }35 36 37 }
nameservice

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  * Created by helloworld on 2014/11/22.13  */14 @Controller15 public class mybatisController {16 17     @Autowired18     NameService nameService;19 20     @RequestMapping(value = "/addName", method = RequestMethod.POST)21     ModelMap addName(@RequestParam("hasException") boolean hasException) {22         try {23             nameService.addQaAndDev(hasException);24         } catch (Exception e) {25             e.printStackTrace();26             return new ModelMap("false");27         }28         return new ModelMap("true");29     }30 31 32 }
controller

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

測試:

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

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

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

 request parameters: hasException=true

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鲜城| 宿迁市| 喀喇沁旗| 油尖旺区| 利津县| 铁岭市| 惠安县| 布尔津县| 乳山市| 响水县| 万源市| 象州县| 合作市| 日土县| 黄龙县| 平凉市| 瑞安市| 山阴县| 泽普县| 石门县| 温州市| 林州市| 合阳县| 松原市| 永顺县| 灵丘县| 浦江县| 安达市| 应城市| 仙居县| 科技| 邢台县| 寻甸| 毕节市| 博爱县| 和政县| 和政县| 永寿县| 广汉市| 京山县| 博爱县|