<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
框架之前完成了多資料來源的動態切換及事務的處理,想更近一步提供一個簡單的跨庫事務處理功能,經過網上的搜尋調研,大致有XA事務/SEGA事務/TCC事務等方案,因為業務主要涉及政府及企業且並行量不大,所以採用XA事務,雖然效能有所損失,但是可以保證資料的強一致性
針對註冊的資料來源拷貝一份用於XA事務,使得本地事務和XA全域性事務相互獨立可選擇的使用
引入atomikos第三方元件
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>
使用Druid連線池,需要使用DruidXADataSource資料來源物件,再使用AtomikosDataSourceBean進行包裝
註冊資料來源時針對同一個連線註冊兩份,一份正常資料來源,一份用於XA事務的資料來源,資料來源標識區分並關聯
因為spring預設註冊了XA事務管理器後,所有事務操作不再走本地事務,我們通過切換不同的資料來源決定走本地事務還是XA事務
//主資料來源xa模式 @Bean @Qualifier("masterXADataSource") public DataSource masterXADataSource() { DruidXADataSource datasource = new DruidXADataSource(); if(driverClassName.equals("com.mysql.cj.jdbc.Driver")){ if(!dbUrl.contains("useOldAliasMetadataBehavior")){ dbUrl += "&useOldAliasMetadataBehavior=true"; } if(!dbUrl.contains("useAffectedRows")){ dbUrl += "&useAffectedRows=true"; } } datasource.setUrl(this.dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); //configuration datasource.setInitialSize(1); datasource.setMinIdle(3); datasource.setMaxActive(20); datasource.setMaxWait(60000); datasource.setTimeBetweenEvictionRunsMillis(60000); datasource.setMinEvictableIdleTimeMillis(60000); datasource.setValidationQuery("select 'x'"); datasource.setTestWhileIdle(true); datasource.setTestOnBorrow(false); datasource.setTestOnReturn(false); datasource.setPoolPreparedStatements(true); datasource.setMaxPoolPreparedStatementPerConnectionSize(20); datasource.setLogAbandoned(false); //移除洩露連線發生是是否記錄紀錄檔 try { datasource.setFilters("stat,slf4j"); } catch (SQLException e) { logger.error("druid configuration initialization filter", e); } datasource.setConnectionProperties("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000");//connectionProperties); AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean(); atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource"); atomikosDataSourceBean.setUniqueResourceName("master-xa"); atomikosDataSourceBean.setXaDataSource(datasource); atomikosDataSourceBean.setPoolSize(5); atomikosDataSourceBean.setMaxPoolSize(20); atomikosDataSourceBean.setTestQuery("select 1"); return atomikosDataSourceBean; }
使用spring內建的JtaTransactionManager事務管理器物件,設定AllowCustomIsolationLevels為true,否則指定自定義事務隔離級別會報錯
//xa模式全域性事務管理器 @Bean(name = "jtaTransactionManager") public PlatformTransactionManager transactionManager() throws Throwable { UserTransactionManager userTransactionManager = new UserTransactionManager(); UserTransaction userTransaction = new UserTransactionImp(); JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(userTransaction, userTransactionManager); jtaTransactionManager.setAllowCustomIsolationLevels(true); return jtaTransactionManager; }
自定義註解@GlobalTransactional並定義對應切面,使用指定註解時在ThreadLocal變數值進行標識,組合
@Transactional註解指定XA事務管理器,在切換資料原時判斷當前是否在XA事物中,從而切換不同的資料來源
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_UNCOMMITTED,transactionManager = "jtaTransactionManager") public @interface GlobalTransactional { }
@Aspect @Component @Order(value = 99) public class GlobalTransitionAspect { private static Logger logger = LoggerFactory.getLogger(GlobalTransitionAspect.class); @Autowired private DynamicDataSource dynamicDataSource; /** * 切面點 指定註解 */ @Pointcut("@annotation(com.code2roc.fastkernel.datasource.GlobalTransactional) " + "|| @within(com.code2roc.fastkernel.datasource.GlobalTransactional)") public void dataSourcePointCut() { } /** * 攔截方法指定為 dataSourcePointCut */ @Around("dataSourcePointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); GlobalTransactional methodAnnotation = method.getAnnotation(GlobalTransactional.class); if (methodAnnotation != null) { DataSourceContextHolder.tagGlobal(); logger.info("標記全域性事務"); } try { return point.proceed(); } finally { logger.info("清除全域性事務"); DataSourceContextHolder.clearGlobal(); } } }
public class DataSourceContextHolder { private static Logger log = LoggerFactory.getLogger(DataSourceContextHolder.class); // 對當前執行緒的操作-執行緒安全的 private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); private static final ThreadLocal<String> contextGlobalHolder = new ThreadLocal<String>(); // 呼叫此方法,切換資料來源 public static void setDataSource(String dataSource) { contextHolder.set(dataSource); log.debug("已切換到資料來源:{}", dataSource); } // 獲取資料來源 public static String getDataSource() { String value = contextHolder.get(); if (StringUtil.isEmpty(value)) { value = "master"; } if (!StringUtil.isEmpty(getGlobal())) { value = value + "-xa"; } return value; } // 刪除資料來源 public static void clearDataSource() { contextHolder.remove(); log.debug("已切換到主資料來源"); } //====================全域性事務標記================ public static void tagGlobal() { contextGlobalHolder.set("1"); } public static String getGlobal() { String value = contextGlobalHolder.get(); return value; } public static void clearGlobal() { contextGlobalHolder.remove(); } //=================================================== }
通過在resource資料夾下建立transactions.properties檔案可以指定XA事務紀錄檔的儲存路徑
com.atomikos.icatch.log_base_dir= tempfiles/transition/
到此這篇關於SpringBoot整合atomikos實現跨庫事務的文章就介紹到這了,更多相關SpringBoot整合atomikos內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45