跨數(shù)據(jù)庫的事務(wù),只能在業(yè)務(wù)上保證。
不能保證的是,2個SQL能夠在同一時間成功。
業(yè)務(wù)上的先期檢查、校驗(yàn)、分布式鎖的設(shè)計,再加上一部分的措施(不停重試、先劃一部分蛋糕再恢復(fù))是必須要考慮的問題和方案。
http://dangdangdotcom.github.io/sharding-jdbc/post/soft_transaction/
http://dangdangdotcom.github.io/sharding-jdbc/post/transaction/
最大努力送達(dá)型
概念
在分布式數(shù)據(jù)庫的場景下,相信對于該數(shù)據(jù)庫的操作最終一定可以成功,所以通過最大努力反復(fù)嘗試送達(dá)操作。
架構(gòu)圖

適用場景
- 根據(jù)主鍵刪除數(shù)據(jù)。
- 更新記錄永久狀態(tài),如更新通知送達(dá)狀態(tài)。
使用限制
使用最大努力送達(dá)型柔性事務(wù)的SQL
需要滿足冪等性。
- INSERT語句要求必須包含主鍵,且不能是自增主鍵。
- UPDATE語句要求冪等,不能是
UPDATE xxx SET x=x+1
- DELETE語句無要求。
開發(fā)指南
Sharding-JDBC-transaction
完全基于java
開發(fā),直接提供jar
包,可直接使用maven導(dǎo)入坐標(biāo)即可使用。- 為了保證事務(wù)不丟失,
Sharding-JDBC-transaction
需要提供數(shù)據(jù)庫存儲事務(wù)日志,配置方法可參見事務(wù)管理器配置項(xiàng)。 - 由于柔性事務(wù)采用異步嘗試,需要部署獨(dú)立的作業(yè)和
Zookeeper
。Sharding-JDBC-transaction
采用elastic-job
實(shí)現(xiàn)的Sharding-JDBC-transaction-async-job
,通過簡單配置即可啟動高可用作業(yè)異步送達(dá)柔性事務(wù),啟動腳本為start.sh
。 - 為了便于開發(fā),
Sharding-JDBC-transaction
提供了基于內(nèi)存的事務(wù)日志存儲器和內(nèi)嵌異步作業(yè)。
開發(fā)示例
// 1. 配置SoftTransactionConfiguration SoftTransactionConfiguration transactionConfig = new SoftTransactionConfiguration(dataSource); transactionConfig.setXXX(); // 2. 初始化SoftTransactionManager SoftTransactionManager transactionManager = new SoftTransactionManager(transactionConfig); transactionManager.init(); // 3. 獲取BEDSoftTransaction BEDSoftTransaction transaction = (BEDSoftTransaction) transactionManager.getTransaction(SoftTransactionType.BestEffortsDelivery); // 4. 開啟事務(wù) transaction.begin(connection); // 5. 執(zhí)行JDBC /* codes here */ * // 6.關(guān)閉事務(wù) transaction.end();
事務(wù)管理器配置項(xiàng)
SoftTransactionConfiguration
配置
用于配置事務(wù)管理器。
名稱 | 類型 | 必填 | 默認(rèn)值 | 說明 |
---|
shardingDataSource | ShardingDataSource | 是 | | 事務(wù)管理器管理的數(shù)據(jù)源 |
syncMaxDeliveryTryTimes | int | 否 | 3 | 同步的事務(wù)送達(dá)的最大嘗試次數(shù) |
storageType | enum | 否 | RDB | 事務(wù)日志存儲類型。可選值: RDB,MEMORY。使用RDB類型將自動建表 |
transactionLogDataSource | DataSource | 否 | null | 存儲事務(wù)日志的數(shù)據(jù)源,如果storageType為RDB則必填 |
bestEffortsDeliveryJobConfiguration | NestedBestEffortsDeliveryJobConfiguration | 否 | null | 最大努力送達(dá)型內(nèi)嵌異步作業(yè)配置對象。如需使用,請參考NestedBestEffortsDeliveryJobConfiguration 配置 |
NestedBestEffortsDeliveryJobConfiguration
配置 (僅開發(fā)環(huán)境)
用于配置內(nèi)嵌的異步作業(yè),僅用于開發(fā)環(huán)境。生產(chǎn)環(huán)境應(yīng)使用獨(dú)立部署的作業(yè)版本。
名稱 | 類型 | 必填 | 默認(rèn)值 | 說明 |
---|
zookeeperPort | int | 否 | 4181 | 內(nèi)嵌的注冊中心端口號 |
zookeeperDataDir | String | 否 | target/test_zk_data/nano/ | 內(nèi)嵌的注冊中心的數(shù)據(jù)存放目錄 |
asyncMaxDeliveryTryTimes | int | 否 | 3 | 異步的事務(wù)送達(dá)的最大嘗試次數(shù) |
asyncMaxDeliveryTryDelayMillis | long | 否 | 60000 | 執(zhí)行異步送達(dá)事務(wù)的延遲毫秒數(shù),早于此間隔時間的入庫事務(wù)才會被異步作業(yè)執(zhí)行 |
獨(dú)立部署作業(yè)指南
- 部署用于存儲事務(wù)日志的數(shù)據(jù)庫。
- 部署用于異步作業(yè)使用的
Zookeeper
。 - 配置
yaml
文件,參照示例。 - 下載并解壓文件
sharding-jdbc-transaction-async-job-$VERSION.tar
,通過start.sh
腳本啟動異步作業(yè)。
異步作業(yè)yaml文件配置
#目標(biāo)數(shù)據(jù)庫的數(shù)據(jù)源. targetDataSource: ds_0: !!org.apache.commons.dbcp.BasicDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/ds_0 username: root password: ds_1: !!org.apache.commons.dbcp.BasicDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/ds_1 username: root password: #事務(wù)日志的數(shù)據(jù)源. transactionLogDataSource: ds_trans: !!org.apache.commons.dbcp.BasicDataSource driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/trans_log username: root password: #注冊中心配置 zkConfig: #注冊中心的連接地址 connectionString: localhost:2181 #作業(yè)的命名空間 namespace: Best-Efforts-Delivery-Job #注冊中心的等待重試的間隔時間的初始值 baseSleepTimeMilliseconds: 1000 #注冊中心的等待重試的間隔時間的最大值 maxSleepTimeMilliseconds: 3000 #注冊中心的最大重試次數(shù) maxRetries: 3 #作業(yè)配置 jobConfig: #作業(yè)名稱 name: bestEffortsDeliveryJob #觸發(fā)作業(yè)的cron表達(dá)式 cron: 0/5 * * * * ? #每次作業(yè)獲取的事務(wù)日志最大數(shù)量 transactionLogFetchDataCount: 100 #事務(wù)送達(dá)的最大嘗試次數(shù). maxDeliveryTryTimes: 3 #執(zhí)行送達(dá)事務(wù)的延遲毫秒數(shù),早于此間隔時間的入庫事務(wù)才會被作業(yè)執(zhí)行 maxDeliveryTryDelayMillis: 60000
事務(wù)支持說明
Sharding-JDBC
由于性能方面的考量,決定不支持強(qiáng)一致性
分布式事務(wù)。我們已明確規(guī)劃線路圖,未來會支持最終一致性的柔性事務(wù)。
目前最大努力送達(dá)型
柔性事務(wù)已開發(fā)完成。
如果不使用柔性事務(wù),也會自動包含弱XA
事務(wù)支持,有以下幾點(diǎn)說明:
完全支持非跨庫事務(wù),例如:僅分表,或分庫但是路由的結(jié)果在單庫中。
完全支持因邏輯異常導(dǎo)致的跨庫事務(wù)。例如:同一事務(wù)中,跨兩個庫更新。更新完畢后,拋出空指針,則兩個庫的內(nèi)容都能回滾。
不支持因網(wǎng)絡(luò)、硬件異常導(dǎo)致的跨庫事務(wù)。例如:同一事務(wù)中,跨兩個庫更新,更新完畢后、未提交之前,第一個庫死機(jī),則只有第二個庫數(shù)據(jù)提交。