gdx 发表于 2015-8-8 09:10:45

使用spring+mybatis+atomikos+tomcat构建分布式事务

  本文通过一个demo,介绍如何使用spring+mybatis+atomikos+tomcat构建在一个事务中涉及两个数据源的web应用。
  demo功能:实现一个能成功提交和回滚的涉及两个数据库数据源的XA事务。
  demo将实现:
  1.一次性在两个数据库的两张表中各插入一条数据并提交。
  2.一次性在两个数据库的两张表中各插入一条数据并回滚。
  测试方式:restful web api
  
  使用工具:
  spring 4.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
4CREATETABLE `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   CREATETABLE `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
2
9   
10         
11   
12   
13   
14
15   
17         
18         
19         
20         
21         
22         
23         
24         
25         
26         
27         
28             select 1
29         
30   
31   
32   
33         
34         
35         
37         
38            
39               ${qa.db.url}
40               ${qa.db.user}
41               ${qa.db.password}
42               true
43            
44         
45   
46
47   
48         
49         
50         
52         
53            
54               ${dev.db.url}
55               ${dev.db.user}
56               ${dev.db.password}
57               true
58            
59         
60   
61
62
63
64   
65         
66         
67   
68
69   
70         
71         
72   
73
74   
76         
77             true
78         
79   
80   
81         
82   
83
84   
86         
87            
88         
89         
90            
91         
92         
93         
94
95   
96
97
98
99   
100         
101         
102   
103
104   
105         
106         
107   
108
  其中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 @Service
15 public class NameService {
16   @Autowired
17   NameQaMapper nameQaMapper;
18   @Autowired
19   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 @Controller
15 public class mybatisController {
16
17   @Autowired
18   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.POSThttp://localhost:8080/mybatis/addName.json

request parameters: hasException=false
返回:true 数据添加成功

  2.POSThttp://localhost:8080/mybatis/addName.json
   request parameters: hasException=true


返回:false 两个数据库数据都未添加
源码下载:http://files.iyunv.com/files/rain-in-sun/springmvc-mybatis-atomikos.rar
  
  
  
  
  
  
  
  
  
  
  
页: [1]
查看完整版本: 使用spring+mybatis+atomikos+tomcat构建分布式事务