分散式事務和資料來源配置
【主題】透過修改Jboss資料來源配置保證I2SS 中事務操作完整性
【關鍵詞】JTA, UserTransaction, xa-datasource,localtx-datasource
【分類】資料庫 / 編碼實現
【提供者】趙學慧 系統設計部
【問題描述】
場景描述:
在EA 公共管理系統中進行刪除使用者操作。使用技術框架I2SS ,應用伺服器Jboss4.0.2,資料庫 MySql 。
具體問題:
EA 公共管理系統刪除使用者時涉及的操作非常之多,如果刪除失敗,發現出現事務不能回滾,雖然在程式碼中已經進行了事務操作的控制。
【原因分析及解決方法】
透過對Mysql日誌進行分析,發現在一次使用者刪除操作中並不是單純的使用單個資料庫連線來完成。透過進一步的跟蹤發現,在I2SS中每一次呼叫資料庫操作的方法總會試圖獲取一個新的connection。而且還有一個嚴重的問題就是我們的程式中利用UserTransaction 對事務進行控制(注 此API 僅用於控制JTA事務),而我們的資料來源配置確是<local-tx-datasource>。如果利用JTA控制事務,而資料來源是本地事務資料來源的,兩者搭配的情況是事務不會起作用,這就意味著從 JDBC 連線池接收連線時,會從該池將 AutoCommit 設定為 true。這就預示我們的JTA事務控制根本就不起作用。這也就解釋了為什麼使用者刪除事務操作失敗的原因。
為了支援I2SS框架,目前的解決方式就是替換支援分散式事務的驅動,修改資料來源配置將其替換成<xa-datasource>。配置檔案如下:
<datasources>
<xa-datasource>
<jndi-name>DataSource</jndi-name>
<track-connection-by-tx>true</track-connection-by-tx>
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
<new-connection-sql>set autocommit=1</new-connection-sql>
<no-tx-separate-pools>true</no-tx-separate-pools>
<xa-datasource-property name="Url">jdbc:mysql://127.0.0.1:3306/sms1?autoReconnect=true</xa-datasource-property>
<xa-datasource-property name="User">smsdb</xa-datasource-property>
<xa-datasource-property name="Password">smsdb</xa-datasource-property>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<type-mapping>mySQL</type-mapping>
<!--pooling parameters-->
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
</xa-datasource>
</datasources>
在上述配置檔案中使用者色標記出的元素需要特別注意,而且這四個配置元素必須同時使用。下面將進行詳細解釋:
1、<no-tx-separate-pools>
這個元素的設定使得兩個連線池能夠分開:一個支援JTA事務的連線,另一個不支援JTA事務的連線。連線池在第一次使用時建立。
2、<track-connection-by-tx>
當這個值設定為true時,連線管理器會保持一個XID-to-connection影射表,當事務結束時而且所有的連線關閉或者未被引用時連線將放回連線池。這樣做的副作用是不會掛起或者恢復連線的XAResource裡的XID,這個行為和本地事務是一樣的。
3、<xa-datasource-class>
指定javax.sql.XASDataSource實現類的全名
4、<new-connection-sql>
當新的連線建立時執行此語句。
在我們的配置檔案中,我們進行了如下配置:
<new-connection-sql> set autocommit=1</new-connection-sql>
這樣做的原因是因為我們透過MySQLXADataSource中獲取的連線預設被設定成autocommit 為false,如果我們的連線併入到事務中時(即事務啟動之後獲取的連線),會統一由UserTransaction 進行提交。對於那些沒有併入事務中的單連線,就會出現操作一直不能提交的錯誤,可能出現XAER_OUTSIDE 異常。透過上述的設定,我們可以將單連線操作放入一個隔離的連線池中,並將其設定為自動提交。
【避免此類問題的建議】
產生這個問題的原因可以歸結為I2SS框架中事務處理不當,connection 封裝不合理。為了適應框架改用分散式事務,理論上講會造成非常大的效能開銷。
【關鍵詞】JTA, UserTransaction, xa-datasource,localtx-datasource
【分類】資料庫 / 編碼實現
【提供者】趙學慧 系統設計部
【問題描述】
場景描述:
在EA 公共管理系統中進行刪除使用者操作。使用技術框架I2SS ,應用伺服器Jboss4.0.2,資料庫 MySql 。
具體問題:
EA 公共管理系統刪除使用者時涉及的操作非常之多,如果刪除失敗,發現出現事務不能回滾,雖然在程式碼中已經進行了事務操作的控制。
【原因分析及解決方法】
透過對Mysql日誌進行分析,發現在一次使用者刪除操作中並不是單純的使用單個資料庫連線來完成。透過進一步的跟蹤發現,在I2SS中每一次呼叫資料庫操作的方法總會試圖獲取一個新的connection。而且還有一個嚴重的問題就是我們的程式中利用UserTransaction 對事務進行控制(注 此API 僅用於控制JTA事務),而我們的資料來源配置確是<local-tx-datasource>。如果利用JTA控制事務,而資料來源是本地事務資料來源的,兩者搭配的情況是事務不會起作用,這就意味著從 JDBC 連線池接收連線時,會從該池將 AutoCommit 設定為 true。這就預示我們的JTA事務控制根本就不起作用。這也就解釋了為什麼使用者刪除事務操作失敗的原因。
為了支援I2SS框架,目前的解決方式就是替換支援分散式事務的驅動,修改資料來源配置將其替換成<xa-datasource>。配置檔案如下:
<datasources>
<xa-datasource>
<jndi-name>DataSource</jndi-name>
<track-connection-by-tx>true</track-connection-by-tx>
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
<new-connection-sql>set autocommit=1</new-connection-sql>
<no-tx-separate-pools>true</no-tx-separate-pools>
<xa-datasource-property name="Url">jdbc:mysql://127.0.0.1:3306/sms1?autoReconnect=true</xa-datasource-property>
<xa-datasource-property name="User">smsdb</xa-datasource-property>
<xa-datasource-property name="Password">smsdb</xa-datasource-property>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<exception-sorter-class-name>
org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter
</exception-sorter-class-name>
<type-mapping>mySQL</type-mapping>
<!--pooling parameters-->
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
</xa-datasource>
</datasources>
在上述配置檔案中使用者色標記出的元素需要特別注意,而且這四個配置元素必須同時使用。下面將進行詳細解釋:
1、<no-tx-separate-pools>
這個元素的設定使得兩個連線池能夠分開:一個支援JTA事務的連線,另一個不支援JTA事務的連線。連線池在第一次使用時建立。
2、<track-connection-by-tx>
當這個值設定為true時,連線管理器會保持一個XID-to-connection影射表,當事務結束時而且所有的連線關閉或者未被引用時連線將放回連線池。這樣做的副作用是不會掛起或者恢復連線的XAResource裡的XID,這個行為和本地事務是一樣的。
3、<xa-datasource-class>
指定javax.sql.XASDataSource實現類的全名
4、<new-connection-sql>
當新的連線建立時執行此語句。
在我們的配置檔案中,我們進行了如下配置:
<new-connection-sql> set autocommit=1</new-connection-sql>
這樣做的原因是因為我們透過MySQLXADataSource中獲取的連線預設被設定成autocommit 為false,如果我們的連線併入到事務中時(即事務啟動之後獲取的連線),會統一由UserTransaction 進行提交。對於那些沒有併入事務中的單連線,就會出現操作一直不能提交的錯誤,可能出現XAER_OUTSIDE 異常。透過上述的設定,我們可以將單連線操作放入一個隔離的連線池中,並將其設定為自動提交。
【避免此類問題的建議】
產生這個問題的原因可以歸結為I2SS框架中事務處理不當,connection 封裝不合理。為了適應框架改用分散式事務,理論上講會造成非常大的效能開銷。
相關文章
- java DB 雙資料來源和資料庫事務配置Java資料庫
- 分散式事務和分散式hash分散式
- 請教一個關於多資料來源的分散式事務問題?分散式
- springboot+ mybatisplus+druid 實現多資料來源+分散式事務Spring BootMyBatisUI分散式
- 分散式事務之資料庫事務與JDBC事務實現(一)分散式資料庫JDBC
- 分散式事務(一)—分散式事務的概念分散式
- 實現多資料來源事務
- 來了!阿里開源分散式事務解決方案 Fescar阿里分散式
- 來了!阿里開源分散式事務解決方案Fescar阿里分散式
- 基於註解的Spring多資料來源配置和使用(非事務)Spring
- 本地事務和分散式事務的區別分散式
- Spring 4+atomikos+JdbcTemplate+DynamicDataSource 分散式事務資料來源動態切換SpringJDBC分散式
- AlwaysOn 可用性組或資料庫映象不支援跨資料庫事務和分散式事務資料庫分散式
- 資料庫分散式事務的實現原理!資料庫分散式
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- 阿里分散式事務框架GTS開源啦!阿里分散式框架
- 分散式事務,原來可以這麼玩?分散式
- 分散式事務(4)---RocketMQ實現分散式事務專案分散式MQ
- 「分散式技術專題」事務型、分析型資料資源隔離機制分散式
- 分散式事務概述分散式
- 理解分散式事務分散式
- 分散式事務--CAP分散式
- 【ITOO】--分散式事務分散式
- WS分散式事務分散式
- oracle分散式事務Oracle分散式
- 聊聊分散式事務分散式
- seata 分散式事務分散式
- 分散式鎖和spring事務管理分散式Spring
- 分散式系統(三)——分散式事務分散式
- spring多資料來源下 事務不生效Spring
- 使用CRDT實現分散式事務的資料推薦分散式
- 微服務分散式事務解決方案-開源軟體seata微服務分散式
- 分散式系列七: 分散式事務理論分散式
- 分散式和事務你真的很熟嗎?分散式
- 分散式事務及其CAP和base理論分散式
- 你真的很熟分散式和事務嗎?分散式
- 分散式事務實戰分散式
- 分散式事務總結分散式