您现在的位置是:亿华云 > 知识
@Transactional 竟也能解决分布式事务?
亿华云2025-10-04 03:18:30【知识】0人已围观
简介前天朋友咨询过我一个问题,大致内容如下:这位读者什么意思呢?简单的总结下:在Sharding-JDBC中明明只是简单的使用@Transactional这个本地事务注解,为什么在跨库插入数据时候却能够同
前天朋友咨询过我一个问题,竟解决大致内容如下:
这位读者什么意思呢?分布简单的总结下:在Sharding-JDBC中明明只是简单的使用@Transactional这个本地事务注解,为什么在跨库插入数据时候却能够同时回滚?式事
我们知道单数据节点的情况下保持事务是非常简单的,只需要使用本地事务即可轻松解决,竟解决比如常用的分布注解:@Transactional。
但是式事在分库后将会存在跨库的事务,此时本地事务还能保证事务吗?竟解决
这篇文章就以球友的提问来聊一下Sharding-JDBC中的本地事务。
本地事务Sharding-JDBC中的分布本地事务可能会让大家有一个误解,还是式事以商品表为例:将商品表根据商品ID进行水平分库,分为两个库,竟解决如下:
分库的分布配置这里就不贴了,详情看源码。式事
此时向其中批量插入数据,竟解决伪代码如下:
@Transactional
public int insertBatch(){
for(int i=0;i<10;i++){
insert(product);
.......
}
}上述案例中使用了@Transactional开启了本地事务,分布但是式事内部在插入数据时,Sharding-JDB会根据product_id这个分片键进行分库,那么这个业务方法肯定是跨了DB1、DB2这两个库,服务器租用@Transactional这个注解能解决吗?
假象:手动在内部模拟抛出异常,还真的是都rollback了。
此时很多人都迷糊了,Sharding-JDBC中的本地事务真的是可以保证分布式事务?
真实结论:Sharding-JDBC中的本地事务无法保证分布式事。
Sharding-JDBC中的本地事务在以下两种情况是完全支持的:
支持非跨库事务,比如仅分表、在单库中操作。支持因逻辑异常导致的跨库事务,比如上述的操作,跨两个库插入数据,插入完成后抛出异常。本地事务不支持的情况:
不支持因网络、硬件异常导致的跨库事务;例如:同一事务中,跨两个库更新,更新完毕后、未提交之前,第一个库宕机,则只有第二个库数据提交。对于因网络、硬件异常导致的亿华云计算跨库事务无法支持很好理解,在分布式事务中无论是两阶段还是三阶段提交都是直接或者间接满足以下两个条件:
有一个事务协调者事务日志记录本地事务并未满足上述条件,自然是无法支持为什么逻辑异常导致的跨库事务能够支持?
Spring的本地事务大家都很了解,也经常用,并不支持的跨库事务,那么为什么Sharding-JDBC中却能支持呢?
想要了解其中的猫腻必然需要从Sharding-JDBC的源码入手,下图是在Sharding-JDBC一条SQL处理的流程:
Sharding-JDBC中的一条SQL会经过改写,拆分成不同数据源的SQL,比如一条select语句,会按照其中分片键拆分成对应数据源的SQL,然后在不同数据源中的执行,最终会提交或者回滚。
想要解释上述的问题,只需要看ShardingConnection,这是Sharding-JDBC自定义实现的,源码下载继承关系如下图:
可以看到ShardingConnection继承了java.sql.Connection,这个类就不必多解释了,在学习JDBC的时候应该都有所接触,直接和数据库打交道的一个类。
想要知道为什么支持跨库事务的回滚,肯定要找到其中的rollback方法,如下:
@Override
public void rollback() throws SQLException {
//① 本地事务
f (TransactionType.LOCAL == transactionType) {
super.rollback();
} else {
//② 非本地事务
shardingTransactionManager.rollback();
}
}rollback的方法中区分了本地事务和分布式事务,如果是本地事务将调用父类的rollback方法,如下:
//父类:AbstractConnectionAdapter#rollback
@Override
public void rollback() throws SQLException {
//cachedConnections中存储了数据源,这里是ds1/ds2
forceExecuteTemplate.execute(cachedConnections.values(), Connection::rollback);
}这里是调用ForceExecuteTemplate#execute()方法执行,其实内部就是遍历数据源去执行对应的rollback方法,如下:
public void execute(final Collection
Collection
for (T each : targets) {
try {
callback.execute(each);
} catch (final SQLException ex) {
exceptions.add(ex);
}
}
throwSQLExceptionIfNecessary(exceptions);
}看到这里已经很明了了,rollback 在各个数据源中回滚且未记录任何事务日志,因此在非硬件、网络的情况下都是可以正常回滚的,一旦因为网络、硬件故障,可能导致某个数据源rollback失败,这样即使程序恢复了正常,也无undo日志继续进行rollback,因此这里就造成了数据不一致了。
总结仅仅依靠Spring自带的本地事务(@Transactional)是无法保证跨库的分布式事务,不要被Sharding-JDBC的假象迷惑了。
当然Sharding-JDBC对于跨库事务也是有一定的支持,大致分成三类:
强一致性的XA协议事务基于Base的柔性事务通过SPI机制自定义扩展的分布式事务解决方案本文只是抛砖引玉简单的介绍下分库分表后的事务处理,后文会针对以上三类方案详细介绍一下。
很赞哦!(139)
相关文章
- 付款完成后,您只需耐心等待,如果您注册成功,系统会提示您。这里需要注意的是,域名是一个即时产品,只有在最终付款成功时才能预订,注册成功后不能更改。
- 4、企业无形资产:通用网站已成为企业网络知识产权的重要组成部分,属于企业的无形资产,也有助于提升企业的品牌形象和技术领先形象。它是企业品牌资产不可或缺的一部分。
- 为啥修改dns服务器?dns服务器与域名有何联系?
- .com域名是国际最广泛流行的通用域名,目前全球注册量第一的域名,公司企业注册域名的首选。国际化公司通常会注册该类域名。
- CNAME:对应解析的记录值为域名地址
- 互联网其实拼的也是人脉,域名投资也是一个时效性很强的东西,一个不起眼的消息就会引起整个域名投资市场的动荡,因此拓宽自己的人脉圈,完善自己的信息获取渠道,让自己能够掌握更为多样化的信息,这样才更有助于自己的域名投资。
- 只要我们做的是从目前的市场情况选择域名,从简单易记,从个性特征上,我们就可以找到一个好域名进行注册。域名注册进行域名记录和解析以及绑定网站后,客户可以通过URL登录您的网站。
- 换新域名(重新来过)
- 域后缀首选.com,.net,然后是.cn。后缀选择不当,导致流量损失。域名是企业与互联网网址之间的链接,关键是企业在网络上存在的标志。因此,选择好域名是开展网上工作的首要重要条件。
- 四、长串数字域名
热门文章
- 2、定期提交和投标域名注册。例如,益华网络点击“立即预订”后,平台会抢先为客户注册域名。当然,一个域名可能会被多个客户预订,所以出价最高的人中标。
- 以上的就是为大家介绍的关于域名的详解
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- 公司名字不但要与其经营理念、活动识别相统一,还要能反映公司理念,服务宗旨、商品形象,从而才能使人看到或听到公司的名称就能产生愉快的联想,对商店产生好感。这样有助于公司树立良好的形象。
站长推荐
4、域名传输时,取决于域名原始用户的邮箱是否有效,以及他是否将密码发送到此邮箱。
如果你的潜在终端必须是这个米(域名),那么潜在终端并不多,也没有硬通货,那么你的域名应该在终端有兴趣购买时出售。否则,你可能得自己留着吃。
注册域名要了解几大点?新手有什么方式注册域名?
为啥修改dns服务器?dns服务器与域名有何联系?
便宜域名使用如何?小白可以买到便宜域名吗?
4.域名的整体品牌营销力
解析之后一般在十分钟内生效,如果没有生效可以联系域名服务商进行沟通。
互联网其实拼的也是人脉,域名投资也是一个时效性很强的东西,一个不起眼的消息就会引起整个域名投资市场的动荡,因此拓宽自己的人脉圈,完善自己的信息获取渠道,让自己能够掌握更为多样化的信息,这样才更有助于自己的域名投资。