Atomikos的使用
生活随笔
收集整理的這篇文章主要介紹了
Atomikos的使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第一步:添加依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>第二步:添加配置
spring:datasource:druid:master:username: rootpassword: 123456url: jdbc:mysql://localhost:3307/hotel?serverTimezone=GMT%2b8driver-class-name: com.mysql.cj.jdbc.Driverinitial-size: 5 # 初始化大小min-idle: 10 # 最小連接數max-active: 20 # 最大連接數max-wait: 60000 # 獲取連接時的最大等待時間min-evictable-idle-time-millis: 300000 # 一個連接在池中最小生存的時間,單位是毫秒time-between-eviction-runs-millis: 60000 # 多久才進行一次檢測需要關閉的空閑連接,單位是毫秒filters: stat # 配置擴展插件:stat-監控統計,log4j-日志,wall-防火墻(防止SQL注入),去掉后,監控界面的sql無法統計 ,wallvalidation-query: SELECT 1 # 檢測連接是否有效的 SQL語句,為空時以下三個配置均無效test-on-borrow: true # 申請連接時執行validationQuery檢測連接是否有效,默認true,開啟后會降低性能test-on-return: true # 歸還連接時執行validationQuery檢測連接是否有效,默認false,開啟后會降低性能test-while-idle: true # 申請連接時如果空閑時間大于timeBetweenEvictionRunsMillis,執行validationQuery檢測連接是否有效,默認false,建議開啟,不影響性能second:username: rootpassword: 123456url: jdbc:mysql://localhost:3307/demo?serverTimezone=GMT%2b8driver-class-name: com.mysql.cj.jdbc.Driverinitial-size: 5 # 初始化大小min-idle: 10 # 最小連接數max-active: 20 # 最大連接數max-wait: 60000 # 獲取連接時的最大等待時間min-evictable-idle-time-millis: 300000 # 一個連接在池中最小生存的時間,單位是毫秒time-between-eviction-runs-millis: 60000 # 多久才進行一次檢測需要關閉的空閑連接,單位是毫秒filters: stat # 配置擴展插件:stat-監控統計,log4j-日志,wall-防火墻(防止SQL注入),去掉后,監控界面的sql無法統計 ,wallvalidation-query: SELECT 1 # 檢測連接是否有效的 SQL語句,為空時以下三個配置均無效test-on-borrow: true # 申請連接時執行validationQuery檢測連接是否有效,默認true,開啟后會降低性能test-on-return: true # 歸還連接時執行validationQuery檢測連接是否有效,默認false,開啟后會降低性能test-while-idle: true # 申請連接時如果空閑時間大于timeBetweenEvictionRunsMillis,執行validationQuery檢測連接是否有效,默認false,建議開啟,不影響性能 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl第三步:配置數據庫配置類
這是我的項目結構,mapper分別放在兩個不同的文件夾中,這樣配置類掃描的時候就可以根據不同的包分配數據源,并創建不同的事物。?
1、主配置類
主要配置類主要配置事務管理器和連接池的監控器。
@Configuration public class DataSourceConfig {@Bean(name = "jtaTransactionManager")@Primarypublic JtaTransactionManager regTransactionManager () {UserTransactionManager userTransactionManager = new UserTransactionManager();UserTransaction userTransaction = new UserTransactionImp();return new JtaTransactionManager(userTransaction, userTransactionManager);}//配置Druid的監控//配置一個管理后臺的Servlet@Beanpublic ServletRegistrationBean statViewServlet() {ServletRegistrationBean registrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");Map<String, String> initParams = new HashMap<>();initParams.put("loginUsername", 登錄名); //登錄名initParams.put("loginPassword", 登錄密碼); //登錄密碼initParams.put("allow", "");//默認就是允許所有訪問//initParams.put("deny","127.0.0.1"); //拒接訪問registrationBean.setInitParameters(initParams);return registrationBean;}//配置一個web監控的filter@Beanpublic FilterRegistrationBean webStatFilter() {FilterRegistrationBean bean = new FilterRegistrationBean();bean.setFilter(new WebStatFilter());Map<String, String> initParams = new HashMap<>(16);initParams.put("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");bean.setInitParameters(initParams);bean.setUrlPatterns(Arrays.asList("/*"));return bean;}2、主庫配置類
@Configuration @MapperScan(basePackages = { "com.haiwang.hotel.mapper.master" },sqlSessionFactoryRef = "masterSqlSessionFactory" ) public class MasterDataSourceConfig {@Value("${spring.datasource.druid.master.url}")private String masterUrl;@Value("${spring.datasource.druid.master.username}")private String masterUsername;@Value("${spring.datasource.druid.master.password}")private String masterPassword;public static final String MAPPER_XML_LOCATION = "classpath:mapper/*.xml";@Bean(name = "master")@ConfigurationProperties(prefix = "spring.datasource.druid.master")@Primarypublic DataSource DataSource() {Properties properties = new Properties();properties.setProperty("URL", masterUrl);properties.setProperty("user", masterUsername);properties.setProperty("password", masterPassword);AtomikosDataSourceBean ds = new AtomikosDataSourceBean();ds.setXaProperties(properties);ds.setUniqueResourceName("masterXADataSource");ds.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");return ds;}@Bean(name = "masterSqlSessionFactory")@Primarypublic SqlSessionFactory masterSqlSessionFactory(@Qualifier("master") DataSource dataSource) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource);factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_XML_LOCATION));return factoryBean.getObject();}@Bean@Primary@Qualifier("masterSqlSessionTemplate")public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory masterSqlSessionFactory){return new SqlSessionTemplate(masterSqlSessionFactory);}}3、從庫配置類
@Configuration @MapperScan(basePackages = { "com.haiwang.hotel.mapper.second" },sqlSessionFactoryRef = "secondSqlSessionFactory" ) public class SecondDataSourceConfig {@Value("${spring.datasource.druid.second.url}")private String secondUrl;@Value("${spring.datasource.druid.second.username}")private String secondUsername;@Value("${spring.datasource.druid.second.password}")private String secondPassword;public static final String MAPPER_XML_LOCATION = "classpath:mapper/*.xml";@Bean(name = "second")public DataSource DataSource() {Properties properties = new Properties();properties.setProperty("URL", secondUrl);properties.setProperty("user", secondUsername);properties.setProperty("password", secondPassword);AtomikosDataSourceBean ds = new AtomikosDataSourceBean();ds.setXaProperties(properties);ds.setUniqueResourceName("secondXADataSource");ds.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");return ds;}@Bean(name = "secondSqlSessionTemplate")public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory secondSqlSessionFactory) throws Exception {return new SqlSessionTemplate(secondSqlSessionFactory);}@Bean(name = "secondSqlSessionFactory")public SqlSessionFactory secondSqlSessionFactory(@Qualifier("second") DataSource dataSource) throws Exception {SqlSessionFactoryBean bean = new SqlSessionFactoryBean();bean.setDataSource(dataSource);bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_XML_LOCATION));return bean.getObject();}}第四步:編寫實現類并測試
實現類:
@Autowired private MasterUserMapper masteruserMapper; @Autowired private SecondUserMapper secondUserMapper;@Transactional(transactionManager = "jtaTransactionManager") public void crossDatabaseTransactional(String name) {List<User> users = new LinkedList<>();User user = new User();user.setName("qqqqq");users.add(user);Integer r1 = masteruserMapper.insertUsers(users);Integer r2 = secondUserMapper.insertUsers(users);if(1==1){throw new BizBusinessException(500,"服務器錯誤!");}}測試類:
@SpringBootTest public class HotelTest {@Autowiredprivate MasterUserMapper masterUserMapper;@Autowiredprivate UserService userService;@Testvoid testCrossDatabaseTransactional() {userService.crossDatabaseTransactional("王");} }測試結果:
拋出錯誤后,所有數據回滾并沒有插入數據庫。
?
參考鏈接:
springboot,atomikos分布式事務報錯:com.mysql.jdbc.jdbc2.optional.MysqlXADataSource 找不到-云海天教程
記一次 Atomikos 分布式事務的使用 - 簡書
Atomikos簡介_獵戶星座。的博客-CSDN博客
atomikos JTA/XA全局事務_分布式事務教程_田守枝Java技術博客?
總結
以上是生活随笔為你收集整理的Atomikos的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浏览器兼容性问题2(持续更新中)
- 下一篇: 城市生活APP开发需要具备什么功能