成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

@Transactional 竟也能解決分布式事務(wù)?

開(kāi)發(fā) 前端
在Sharding-JDBC中明明只是簡(jiǎn)單的使用@Transactional這個(gè)本地事務(wù)注解,為什么在跨庫(kù)插入數(shù)據(jù)時(shí)候卻能夠同時(shí)回滾?

前天朋友咨詢過(guò)我一個(gè)問(wèn)題,大致內(nèi)容如下:

圖片

這位讀者什么意思呢?簡(jiǎn)單的總結(jié)下:在Sharding-JDBC中明明只是簡(jiǎn)單的使用@Transactional這個(gè)本地事務(wù)注解,為什么在跨庫(kù)插入數(shù)據(jù)時(shí)候卻能夠同時(shí)回滾?

我們知道單數(shù)據(jù)節(jié)點(diǎn)的情況下保持事務(wù)是非常簡(jiǎn)單的,只需要使用本地事務(wù)即可輕松解決,比如常用的注解:@Transactional。

但是在分庫(kù)后將會(huì)存在跨庫(kù)的事務(wù),此時(shí)本地事務(wù)還能保證事務(wù)嗎?

這篇文章就以球友的提問(wèn)來(lái)聊一下Sharding-JDBC中的本地事務(wù)。

本地事務(wù)

Sharding-JDBC中的本地事務(wù)可能會(huì)讓大家有一個(gè)誤解,還是以商品表為例:將商品表根據(jù)商品ID進(jìn)行水平分庫(kù),分為兩個(gè)庫(kù),如下:

圖片

分庫(kù)的配置這里就不貼了,詳情看源碼。

此時(shí)向其中批量插入數(shù)據(jù),偽代碼如下:

@Transactional
public int insertBatch(){
for(int i=0;i<10;i++){
insert(product);
.......
}
}

上述案例中使用了@Transactional?開(kāi)啟了本地事務(wù),但是內(nèi)部在插入數(shù)據(jù)時(shí),Sharding-JDB會(huì)根據(jù)product_id?這個(gè)分片鍵進(jìn)行分庫(kù),那么這個(gè)業(yè)務(wù)方法肯定是跨了DB1、DB2?這兩個(gè)庫(kù),@Transactional這個(gè)注解能解決嗎?

假象:手動(dòng)在內(nèi)部模擬拋出異常,還真的是都rollback了。

此時(shí)很多人都迷糊了,Sharding-JDBC中的本地事務(wù)真的是可以保證分布式事務(wù)?

真實(shí)結(jié)論:Sharding-JDBC中的本地事務(wù)無(wú)法保證分布式事。

Sharding-JDBC中的本地事務(wù)在以下兩種情況是完全支持的:

  • 支持非跨庫(kù)事務(wù),比如僅分表、在單庫(kù)中操作。
  • 支持因邏輯異常導(dǎo)致的跨庫(kù)事務(wù),比如上述的操作,跨兩個(gè)庫(kù)插入數(shù)據(jù),插入完成后拋出異常。

本地事務(wù)不支持的情況:

  • 不支持因網(wǎng)絡(luò)、硬件異常導(dǎo)致的跨庫(kù)事務(wù);例如:同一事務(wù)中,跨兩個(gè)庫(kù)更新,更新完畢后、未提交之前,第一個(gè)庫(kù)宕機(jī),則只有第二個(gè)庫(kù)數(shù)據(jù)提交。

對(duì)于因網(wǎng)絡(luò)、硬件異常導(dǎo)致的跨庫(kù)事務(wù)無(wú)法支持很好理解,在分布式事務(wù)中無(wú)論是兩階段還是三階段提交都是直接或者間接滿足以下兩個(gè)條件:

  • 有一個(gè)事務(wù)協(xié)調(diào)者
  • 事務(wù)日志記錄

本地事務(wù)并未滿足上述條件,自然是無(wú)法支持

為什么邏輯異常導(dǎo)致的跨庫(kù)事務(wù)能夠支持?

Spring的本地事務(wù)大家都很了解,也經(jīng)常用,并不支持的跨庫(kù)事務(wù),那么為什么Sharding-JDBC中卻能支持呢?

想要了解其中的貓膩必然需要從Sharding-JDBC的源碼入手,下圖是在Sharding-JDBC一條SQL處理的流程:

圖片

Sharding-JDBC中的一條SQL會(huì)經(jīng)過(guò)改寫,拆分成不同數(shù)據(jù)源的SQL,比如一條select語(yǔ)句,會(huì)按照其中分片鍵拆分成對(duì)應(yīng)數(shù)據(jù)源的SQL,然后在不同數(shù)據(jù)源中的執(zhí)行,最終會(huì)提交或者回滾。

想要解釋上述的問(wèn)題,只需要看ShardingConnection,這是Sharding-JDBC自定義實(shí)現(xiàn)的,繼承關(guān)系如下圖:

圖片

可以看到ShardingConnection?繼承了java.sql.Connection,這個(gè)類就不必多解釋了,在學(xué)習(xí)JDBC的時(shí)候應(yīng)該都有所接觸,直接和數(shù)據(jù)庫(kù)打交道的一個(gè)類。

想要知道為什么支持跨庫(kù)事務(wù)的回滾,肯定要找到其中的rollback方法,如下:

@Override
public void rollback() throws SQLException {
//① 本地事務(wù)
f (TransactionType.LOCAL == transactionType) {
super.rollback();
} else {
//② 非本地事務(wù)
shardingTransactionManager.rollback();
}
}

rollback?的方法中區(qū)分了本地事務(wù)和分布式事務(wù),如果是本地事務(wù)將調(diào)用父類的rollback方法,如下:

//父類:AbstractConnectionAdapter#rollback

@Override
public void rollback() throws SQLException {
//cachedConnections中存儲(chǔ)了數(shù)據(jù)源,這里是ds1/ds2
forceExecuteTemplate.execute(cachedConnections.values(), Connection::rollback);
}

這里是調(diào)用ForceExecuteTemplate#execute()?方法執(zhí)行,其實(shí)內(nèi)部就是遍歷數(shù)據(jù)源去執(zhí)行對(duì)應(yīng)的rollback方法,如下:

public void execute(final Collection<T> targets, final ForceExecuteCallback<T> callback) throws SQLException {
Collection<SQLException> exceptions = new LinkedList<>();
for (T each : targets) {
try {
callback.execute(each);
} catch (final SQLException ex) {
exceptions.add(ex);
}
}
throwSQLExceptionIfNecessary(exceptions);
}

看到這里已經(jīng)很明了了,rollback? 在各個(gè)數(shù)據(jù)源中回滾且未記錄任何事務(wù)日志,因此在非硬件、網(wǎng)絡(luò)的情況下都是可以正常回滾的,一旦因?yàn)榫W(wǎng)絡(luò)、硬件故障,可能導(dǎo)致某個(gè)數(shù)據(jù)源rollback失敗,這樣即使程序恢復(fù)了正常,也無(wú)undo日志繼續(xù)進(jìn)行rollback,因此這里就造成了數(shù)據(jù)不一致了。

總結(jié)

僅僅依靠Spring自帶的本地事務(wù)(@Transactional)是無(wú)法保證跨庫(kù)的分布式事務(wù),不要被Sharding-JDBC的假象迷惑了。

當(dāng)然Sharding-JDBC對(duì)于跨庫(kù)事務(wù)也是有一定的支持,大致分成三類:

  • 強(qiáng)一致性的XA協(xié)議事務(wù)
  • 基于Base的柔性事務(wù)
  • 通過(guò)SPI機(jī)制自定義擴(kuò)展的分布式事務(wù)解決方案

本文只是拋磚引玉簡(jiǎn)單的介紹下分庫(kù)分表后的事務(wù)處理,后文會(huì)針對(duì)以上三類方案詳細(xì)介紹一下。

責(zé)任編輯:武曉燕 來(lái)源: 碼猿技術(shù)專欄
相關(guān)推薦

2022-03-24 07:51:27

seata分布式事務(wù)Java

2025-04-29 04:00:00

分布式事務(wù)事務(wù)消息

2022-06-27 08:21:05

Seata分布式事務(wù)微服務(wù)

2022-06-14 10:47:00

分布式事務(wù)數(shù)據(jù)

2022-06-21 08:27:22

Seata分布式事務(wù)

2017-07-26 15:08:05

大數(shù)據(jù)分布式事務(wù)

2023-09-14 15:44:46

分布式事務(wù)數(shù)據(jù)存儲(chǔ)

2020-05-28 09:35:05

分布式事務(wù)方案

2025-04-30 10:44:02

2024-10-09 14:14:07

2019-10-10 09:16:34

Zookeeper架構(gòu)分布式

2009-06-19 15:28:31

JDBC分布式事務(wù)

2009-09-18 15:10:13

分布式事務(wù)LINQ TO SQL

2021-09-29 09:07:37

分布式架構(gòu)系統(tǒng)

2025-04-28 00:44:04

2020-12-09 09:14:57

SpringCloudSeata 分布式

2019-06-26 09:41:44

分布式事務(wù)微服務(wù)

2019-01-11 18:22:07

阿里巴巴技術(shù)開(kāi)源

2010-07-21 13:53:41

SQL Server分

2025-05-15 08:05:00

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 黄色一级特级片 | 国产成人精品a视频一区www | www.久久.com| 亚洲一区二区三区国产 | 四虎网站在线观看 | 亚洲欧美中文日韩在线v日本 | 天堂一区二区三区 | 大陆一级毛片免费视频观看 | 精品一区二区久久 | 色屁屁在线观看 | 日韩成人免费视频 | 久久性色| 9久久 | 久久久婷婷 | 精品欧美乱码久久久久久 | 亚洲国产中文字幕 | 99精品一区 | 日本又色又爽又黄又高潮 | 黄色精品| 精品视频一区在线 | 91影片 | 国产激情精品一区二区三区 | 一级a毛片 | 国产婷婷色一区二区三区 | 91精品一区二区三区久久久久久 | 麻豆视频在线看 | 国产精品永久 | 给我免费的视频在线观看 | 亚洲国产成人精品久久 | cao在线| 色综合99 | www.97国产 | 激情毛片 | 欧美一区二区三区视频在线播放 | 最新日韩欧美 | 欧美一区二区在线观看 | 91天堂| 中文字幕成人 | 欧美 日韩 国产 一区 | av中文字幕在线观看 | 久久一二 |