整合Atomikos、Quartz、Postgresql的踩坑日記

前言

由於業務需要,在單體Spring Boot項目中需要引入分佈式事務,來保證單體應用連接的多個數據源的事務統一。

而說到分佈式事務,小夥伴們肯定會想到阿里的Seata,阿里Seata強大的AT模式確實是解決分佈式事務的一劑良藥,

但是熟悉Seata的小夥伴肯定知道,使用Seata需要單獨搭建Seata服務端來支持分佈式事務,而對於一個單體應用項目有必要專門搭建這套服務端嗎?

這是一個值得考慮的問題。王子認爲技術選型的一個標準就是,用盡可能簡單的方式解決複雜的問題。

於是,Atomikos出現了。至於什麼是Atomikos這裏就不介紹了,網上資料一大堆。本文主要是介紹引入Atomikos後出現的一些問題和解決方案。

引入Atomikos後的第一個坑

好了,下面我們進入正題,看看王子是如何引入Atomikos的。

說明:以下內容不是引入Atomikos的所有工作,王子只是做了個簡單介紹,如果需要完整引入還需要參考其他文章。

要使用Atomikos當然要先在Maven中引入它的依賴了,它的依賴如下:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jta-atomikos</artifactId>
        </dependency>

 

這裏我們省略一些必要的配置內容,

在配置數據源的過程中一定會有類似下邊這部分的代碼,用來配置Atomikos:

        AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
        ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
        ds.setUniqueResourceName(dataSourceName);
        ds.setMinPoolSize(5);
        ds.setMaxPoolSize(20);
        ds.setBorrowConnectionTimeout(60);
        ds.setXaProperties(prop);

第一個坑來了,在配置這部分內容中,王子開始時是沒有配置下邊這部分內容的。

        ds.setMinPoolSize(5);
        ds.setMaxPoolSize(20);
        ds.setBorrowConnectionTimeout(60);

這個時候,運行程序一切正常,包括它的分佈式事務,王子也已經測試通過了。

但是,當運行應用中Quartz定時任務的時候,悲劇發生了,控制檯直接報如下異常:

[ERROR][-- ::,][org.hibernate.engine.jdbc.spi.SqlExceptionHelper]Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.
[ERROR][-- ::,][org.apache.struts2.dispatcher.Dispatcher]Exception occurred during processing request: Could not open connection

現在對於這個第一個坑的解決方案相信大家已經清楚了,就是要配置剛纔我們提到的那三行內容。

第二個坑

現在我們成功的解決了第一個坑,重啓程序再次測試Quartz定時任務,看到應用中那還是一直在轉的圈圈(頭痛)。

經過對報錯日誌的分析之後,發現了一行有用的信息,如下:

Caused by: org.postgresql.util.PSQLException: ERROR: prepared transactions are disabled
  Suggerimento: Set max_prepared_transactions to a nonzero value.

看到這裏其實就很明顯了,翻譯過來就是給max_prepared_transactions這個參數設置一個非0的值。

解決方案就是找到Postgresql數據庫的postgresql.conf文件,修改這個值即可。

max_prepared_transactions默認是0,我們把它改成與max_connections一樣大就可以了。

總結

本文主要是記錄一下日常工作中踩到的坑,防止再犯同樣的問題。

對於第一個坑,屬於Atomikos的配置問題,小夥伴們可以做一個瞭解。

對於第二個坑,王子這裏使用的是Postgresql數據庫,所以導致了這個問提,建議如果使用Postgre數據庫都開啓一下這個參數,防止後患。

最後王子說明一下,Atomikos只適用於類似本文中的這種小規模系統,它的底層是XA的2PC方案,會對數據庫資源有一定的鎖定過程,所以性能不是很高。

所以,對於要考慮高併發、高性能的系統,分佈式事務框架還是要優先選擇Seata。

 

往期文章推薦:

JVM專欄

消息中間件專欄

併發編程專欄

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章