springmvc atomikos mysql数据源_springboot+atomikos+多数据源管理事务(mysql 8.0)
jta:Java Transaction API,即是java中對事務處理的api?即?api即是接口的意思
atomikos:Atomikos TransactionsEssentials 是一個為Java平臺提供增值服務的并且開源類事務管理器
1.結構
2.pom依賴
我這里使用本地數據庫是mysql8,
org.springframework.boot
spring-boot-starter-parent
2.1.0.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.0
org.springframework.boot
spring-boot-starter-jta-atomikos
org.springframework.boot
spring-boot-devtools
runtime
mysql
mysql-connector-java
8.0.13
org.projectlombok
lombok
true
1.18.2
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-configuration-processor
true
3.創建本地數據庫+表
4.application.yml
server:
port: 8080
servlet:
# # 項目contextPath
context-path: /manyDatasource
spring:
application:
name: manyDatasource
datasource:
# spring.datasource.test1
# druid:
test1:
# jdbc-url,url,jdbcurl哪個合適用哪個
jdbcurl: jdbc:mysql://localhost:3306/test1?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
# driver-class-name: com.mysql.jdbc.Driver
# 下面是最新的mysql8版本推薦的驅動
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# 下面是另外加的配置數據源的參數
minPoolSize: 3
maxPoolSize: 25
maxLifetime: 20000
borrowConnectionTimeout: 30
loginTimeout: 30
maintenanceInterval: 60
maxIdleTime: 60
test2:
jdbcurl: jdbc:mysql://localhost:3306/test2?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
minPoolSize: 3
maxPoolSize: 25
maxLifetime: 20000
borrowConnectionTimeout: 30
loginTimeout: 30
maintenanceInterval: 60
maxIdleTime: 60
mybatis:
mapper-locations: classpath:mapper/*.xml
#設置靜態資源路徑,多個以逗號分隔
spring.resources.static-locations: classpath:static/,file:static/
# 日志配置
logging:
level:
czs: debug
org.springframework: WARN
org.spring.springboot.dao: debug
5.實體類
ps.使用lombok插件挺方便的~ ?id數據庫主鍵自增
@Datapublic classUser {privateInteger id;privateString name;private longage;
}
6.mapper接口
UserMapper1:
public interfaceUserMapper1 {//查詢語句
@Select("SELECT * FROM users WHERE NAME = #{name}")
User findByName(@Param("name") String name);//添加
@Insert("INSERT INTO users(NAME, AGE) VALUES(#{name}, #{age})")int insert(@Param("name") String name, @Param("age") Integer age);
}
UserMapper2:
public interfaceUserMapper2 {//查詢語句
@Select("SELECT * FROM users WHERE NAME = #{name}")
User findByName(@Param("name") String name);//添加
@Insert("INSERT INTO users(NAME, AGE) VALUES(#{name}, #{age})")int insert(@Param("name") String name, @Param("age") Integer age);
}
7.service
ManyService1:
@Servicepublic classManyService1 {
@AutowiredprivateUserMapper1 userMapper1;
@AutowiredprivateUserMapper2 userMapper2;/*@Transactional(transactionManager = "test1TransactionManager",rollbackFor = Exception.class)
public int insert(String name, Integer age) {
int i = userMapper1.insert(name, age);
System.out.println("userMapper1.insert結束~ :" + i);
// int a = 1 / 0;//手動異常
return i;
}*/
//開啟事務,由于使用jta+atomikos解決分布式事務,所以此處不必再指定事務
@Transactionalpublic intinsert(String name, Integer age) {int insert =userMapper1.insert(name, age);//int i = 1 / age;//賦值age為0故意引發事務
returninsert;
}//http://localhost:8080/manyDatasource/insertDb1AndDb2?name=tom3&age=2//開啟事務,由于使用jta+atomikos解決分布式事務,所以此處不必再指定事務
@Transactionalpublic intinsertDb1AndDb2(String name, Integer age) {int insert =userMapper1.insert(name, age);int insert2 =userMapper2.insert(name, age);int i = 1 / age;//賦值age為0故意引發事務
return insert +insert2;
}
}
ManyService2:
@Servicepublic classManyService2 {
@AutowiredprivateUserMapper2 userMapper2;
@Transactional(transactionManager= "test2TransactionManager",rollbackFor = Exception.class)public intinsert(String name, Integer age) {int i =userMapper2.insert(name, age);
System.out.println("userMapper2.insert結束~ :" + null);int a = 1 / 0;//手動異常
returni;
}
}
8.Controller
@RestControllerpublic classManyController {
@AutowiredprivateManyService1 manyService1;
@ResourceprivateManyService2 manyService2;
@RequestMapping(value= "datasource1")public intdatasource1(String name, Integer age) {returnmanyService1.insert(name, age);
}
@RequestMapping(value= "datasource2")public intdatasource2(String name, Integer age) {returnmanyService2.insert(name, age);
}/*** @Param:
* @Description: 這里測試兩個service兩個數據源的事務(不加上atomikos插件的情況下測試,
*使用DataSource1Config和DataSource2Config 兩個配置類, 關閉DBConfig1, DBConfig2和MyBatisConfig1, MyBatisConfig1兩個類)
* @Author: zyf 2019/5/10*/
//http://localhost:8080/manyDatasource/testManyTrans?name=tom4&age=2
@RequestMapping(value = "testManyTrans")public inttestManyTrans(String name, Integer age) {int i = 0;int i1 =manyService1.insert(name, age);
System.out.println("manyService1.insert :" +i1);/*第二個事務中會手動造成一個異常~,
但是第一個事務執行完畢了,保存到了數據庫*/
int i2 =manyService2.insert(name, age);
System.out.println("manyService2.insert :" +i2);returni;
}/*** @Param:
* @Description: 這里測試使用atomikos插件測試多數據源事務
* @Author: zyf 2019/5/10*/
//http://localhost:8080/manyDatasource/insertDb1AndDb2?name=tom5&age=2//http://localhost:8080/manyDatasource/insertDb1AndDb2?name=tom6&age=0//測試除數為0后的事務管理
@RequestMapping(value = "insertDb1AndDb2")public intinsertDb1AndDb2(String name, Integer age) {returnmanyService1.insertDb1AndDb2(name, age);
}
}
9.配置數據源(*******重點總是在最后********)
DBConfig1:
@Data
@ConfigurationProperties(prefix= "spring.datasource.test1") //注意這個前綴要和application.yml文件的前綴一樣
public classDBConfig1 {//@Value("${mysql.datasource.test1.jdbcurl}")//@Value("${jdbcurl}")
privateString jdbcurl;//private String url;//比如這個url在properties中是這樣子的mysql.datasource.test1.username = root
privateString username;privateString password;private intminPoolSize;private intmaxPoolSize;private intmaxLifetime;private intborrowConnectionTimeout;private intloginTimeout;private intmaintenanceInterval;private intmaxIdleTime;privateString testQuery;
}
DBConfig2:
@Data
@ConfigurationProperties(prefix= "spring.datasource.test2")//注意這個前綴要和application.yml文件的前綴一樣
public classDBConfig2 {//@Value("${spring.datasource.test2.jdbcurl}")//@Value("${jdbcurl}")//private String url;
privateString jdbcurl;privateString username;privateString password;private intminPoolSize;private intmaxPoolSize;private intmaxLifetime;private intborrowConnectionTimeout;private intloginTimeout;private intmaintenanceInterval;private intmaxIdleTime;privateString testQuery;
}
上面兩個配置類作用:?將application.yml配置文件中配置自動封裝到實體類字段中,然后賦值給atomikos類型的數據源.(下面兩個具體配置數據源)
MyBatisConfig1:
//配置數據源//@Bean(name = "testDataSource")//test1DataSource
@Bean(name = "test1DataSource") //test1DataSource
public DataSource testDataSource(DBConfig1 testConfig) throwsSQLException {
MysqlXADataSource mysqlXaDataSource= newMysqlXADataSource();//mysqlXaDataSource.setUrl(testConfig.getUrl());
mysqlXaDataSource.setUrl(testConfig.getJdbcurl());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(testConfig.getPassword());
mysqlXaDataSource.setUser(testConfig.getUsername());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);//將本地事務注冊到創 Atomikos全局事務
AtomikosDataSourceBean xaDataSource = newAtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("test1DataSource");
xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
xaDataSource.setTestQuery(testConfig.getTestQuery());returnxaDataSource;
}
@Bean(name= "test1SqlSessionFactory")public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)throwsException {
SqlSessionFactoryBean bean= newSqlSessionFactoryBean();
bean.setDataSource(dataSource);returnbean.getObject();
}
@Bean(name= "test1SqlSessionTemplate")publicSqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throwsException {return newSqlSessionTemplate(sqlSessionFactory);
}
MyBatisConfig2 :
@Configuration
@MapperScan(basePackages= "czs.mapper2", sqlSessionTemplateRef = "test2SqlSessionTemplate")public classMyBatisConfig2 {//配置數據源
@Bean(name = "test2DataSource")public DataSource testDataSource(DBConfig2 testConfig) throwsSQLException {
MysqlXADataSource mysqlXaDataSource= newMysqlXADataSource();//mysqlXaDataSource.setUrl(testConfig.getUrl());
mysqlXaDataSource.setUrl(testConfig.getJdbcurl());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(testConfig.getPassword());
mysqlXaDataSource.setUser(testConfig.getUsername());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
AtomikosDataSourceBean xaDataSource= newAtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("test2DataSource");
xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
xaDataSource.setTestQuery(testConfig.getTestQuery());returnxaDataSource;
}
@Bean(name= "test2SqlSessionFactory")public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)throwsException {
SqlSessionFactoryBean bean= newSqlSessionFactoryBean();
bean.setDataSource(dataSource);returnbean.getObject();
}
@Bean(name= "test2SqlSessionTemplate")publicSqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throwsException {return newSqlSessionTemplate(sqlSessionFactory);
}
}
10.測試
http://localhost:8080/manyDatasource/insertDb1AndDb2?name=tom5&age=2
結果: test1和test2數據庫都插入數據~
http://localhost:8080/manyDatasource/insertDb1AndDb2?name=tom6&age=0 (兩個insert操作后,手動異常)
結果: test1和test2數據庫都未插入數據~
GitHub傳送門: https://github.com/ColoZhu/springbootmanyDatasource
參考出處:?https://blog.csdn.net/qq_36138324/article/details/81612890
總結
以上是生活随笔為你收集整理的springmvc atomikos mysql数据源_springboot+atomikos+多数据源管理事务(mysql 8.0)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 控制台怎么退出mysql_退出mysql
- 下一篇: hp-ux mysql_HP-UX安装M