本文環境接上文多數據源配置的環境。java
若是採用不一樣的數據源,當同時對不一樣的數據源進行操做時,事務沒法正確的回滾,此時須要使用MysqlXADataSource來代理數據源。mysql
MybatisDBD1Config.java:spring
package com.bxw.configuration; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; import java.sql.SQLException; /** * 分佈式事務管理 */ @Configuration @MapperScan(basePackages = "com.bxw.mapperTA", sqlSessionTemplateRef = "sqlSessionTemplateT1") public class MybatisDBD1Config { @Primary @Bean(name = "datasourceT1") public DataSource dataSource(DBConfig1 dbConfig1)throws SQLException{ MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(dbConfig1.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(dbConfig1.getPassword()); mysqlXaDataSource.setUser(dbConfig1.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("dbb1"); // xaDataSource.setMinPoolSize(dbConfig1.getMinPoolSize()); // xaDataSource.setMaxPoolSize(dbConfig1.getMaxPoolSize()); // xaDataSource.setMaxLifetime(dbConfig1.getMaxLifetime()); // xaDataSource.setBorrowConnectionTimeout(dbConfig1.getBorrowConnectionTimeout()); // xaDataSource.setLoginTimeout(dbConfig1.getLoginTimeout()); // xaDataSource.setMaintenanceInterval(dbConfig1.getMaintenanceInterval()); // xaDataSource.setMaxIdleTime(dbConfig1.getMaxIdleTime()); // xaDataSource.setTestQuery(dbConfig1.getTestQuery()); return xaDataSource; } @Bean(name = "sqlSessionFactoryT1") public SqlSessionFactory sqlSessionFactory(@Qualifier("datasourceT1") DataSource dataSource) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); // 使用db1數據源, 鏈接hibernate庫 return factoryBean.getObject(); } @Bean(name="sqlSessionTemplateT1") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactoryT1") SqlSessionFactory sqlSessionFactory) throws Exception { SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory); // 使用上面配置的Factory return template; } }
MybatisDBD2Config.java:
package com.bxw.configuration; import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.sql.SQLException; /** * 分佈式事務管理 */ @Configuration @MapperScan(basePackages = "com.bxw.mapperTB", sqlSessionTemplateRef = "sqlSessionTemplateT2") public class MybatisDBD2Config { @Bean(name = "datasourceT2") public DataSource dataSource(DBConfig2 dbConfig2)throws SQLException{ MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(dbConfig2.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(dbConfig2.getPassword()); mysqlXaDataSource.setUser(dbConfig2.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("dbb2"); // xaDataSource.setMinPoolSize(dbConfig1.getMinPoolSize()); // xaDataSource.setMaxPoolSize(dbConfig1.getMaxPoolSize()); // xaDataSource.setMaxLifetime(dbConfig1.getMaxLifetime()); // xaDataSource.setBorrowConnectionTimeout(dbConfig1.getBorrowConnectionTimeout()); // xaDataSource.setLoginTimeout(dbConfig1.getLoginTimeout()); // xaDataSource.setMaintenanceInterval(dbConfig1.getMaintenanceInterval()); // xaDataSource.setMaxIdleTime(dbConfig1.getMaxIdleTime()); // xaDataSource.setTestQuery(dbConfig1.getTestQuery()); return xaDataSource; } @Bean(name = "sqlSessionFactoryT2") public SqlSessionFactory sqlSessionFactory(@Qualifier("datasourceT2") DataSource dataSource) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); // 使用db1數據源, 鏈接hibernate庫 return factoryBean.getObject(); } @Bean(name="sqlSessionTemplateT2") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactoryT2") SqlSessionFactory sqlSessionFactory) throws Exception { SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory); // 使用上面配置的Factory return template; } }
建立sqlSessionFactory,SqlSessionTemplatesql
StudentService.java:apache
package com.bxw.service; import com.bxw.annotation.DB; import com.bxw.entity.Student; import com.bxw.mapperTA.StudentMapperTA; import com.bxw.mapperTB.StudentMapperTB; import com.bxw.mapperDynamic.StudentMapperC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @Service public class StudentService { @Autowired private StudentMapperTA studentMapperTA; @Autowired private StudentMapperTB studentMapperTB;
/* 分佈式事務 */ @Transactional public boolean saveStudent(Student s){ studentMapperTA.addStudent(s); studentMapperTB.addStudent(s); int i = 1/0; return true; } }