老哥们,周二好。问一个跨库保证一致性的问题

2019-11-12 15:53:30 +08:00
 ayonel

业务背景: 有一份数据,需要双写到两份存储( Mysql、Neo4j )

项目基于 springboot.我已经配置了 mysql 数据源的事务管理器,neo4j 没有配置。在不使用分布式事务的前提下,以下这种做法能否保证两份数据的一致性:

@Transactional
public void doService() {
	// 第一步,插 mysql
	insertMysql();
    // 第二步,插 neo4j
    insertNeo4j();
}

思路:

  1. 如果插 mysql 出现异常,此时 mysql 事务直接回滚,neo4j 还没来得及插入。所以最终表现是:两个引擎数据都没写入,保持一致。
  2. 如果插入 neo4j 出现异常,此时 mysql 事务也会回滚。而 neo4j 由于插入失败,也没有数据。所以最终表现是:两个引擎数据都没写入,保持一致。

看起来,这样简单的做法能保证一致性,老哥们能指出这种做法有啥坑吗?( PS:假设 mysql、neo4j 都是一条操作语句)

5668 次点击
所在节点    Java
45 条回复
qiyuey
2019-11-12 16:05:05 +08:00
放弃分布式事务,使用幂等重试
ayonel
2019-11-12 16:21:40 +08:00
这种做法也没有使用分布式事务。老哥看下这种 trick 做法可以保证一致性吗
reus
2019-11-12 16:25:45 +08:00
成功插入 neo4j 之后出现异常,mysql 回滚,而 neo4j 没有,不就不一致了?
cmingxu
2019-11-12 16:33:13 +08:00
感觉能完全说明白这个问题得一本厚书, 期待惊艳回答。
iIli1iIliIllLiL
2019-11-12 16:34:09 +08:00
3L+1
ayonel
2019-11-12 16:39:45 +08:00
@reus @iIli1iIliIllLiL 成功插入 neo4j 之后都没有其他逻辑了,还能发生异常吗?
reus
2019-11-12 16:40:53 +08:00
@ayonel 插入之后进程挂了呢?
lhx2008
2019-11-12 16:42:18 +08:00
@ayonel 能,网络问题,如果插完 neo4j 的瞬间拔了网线,则无法确定 neo4j 是否插入成功。
lhx2008
2019-11-12 16:43:26 +08:00
如果都在一台机器上面其实问题不大,除非进程自己挂了
Yuicon
2019-11-12 16:44:24 +08:00
在回滚的时候添加逻辑删除 neo4j 多余数据
optional
2019-11-12 16:45:07 +08:00
关键是你下面还有代码,,如果你下面的代码抛异常了呢?
ysweics
2019-11-12 16:47:26 +08:00
用 MQ 做最终一致性吧
lhx2008
2019-11-12 16:54:04 +08:00
比较简单的方法就是异步同步,先把资料持久化一份( kafka 等),然后开一个后台程序去读,然后写到 neo4j,当然,代价是没有强一致性。不过强一致性不是那么容易搞的。
ebony0319
2019-11-12 16:55:27 +08:00
用最终一致性和事务补偿。
ayonel
2019-11-12 17:03:52 +08:00
@optional 下面可以认为没代码了
ayonel
2019-11-12 17:04:15 +08:00
@reus 这个概率太小了吧?还有其他 case 能造成数据不一致吗?
wangyzj
2019-11-12 17:04:17 +08:00
tcc
lhx2008
2019-11-12 17:06:14 +08:00
强一致一般可以用 2PC 两阶段提交,两个被调用方要保证落盘一份并能保证插入,然后再返回给调用方 2 个 OK,调用方再发提交给被调用方。如果调用方挂掉,也必须快速重启后跟上进度,否则就会卡住等人工处理。
ayonel
2019-11-12 17:06:33 +08:00
@ysweics
@lhx2008 感觉是个比较简单的业务逻辑,引入 MQ 有些大材小用。大神能指出我题目中这种写法的弊端吗?
ayonel
2019-11-12 17:07:07 +08:00
@wangyzj 不想引入分布式事务。单纯看我题中的解法会产生什么问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/618835

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX