看帖神器
未名空间
追帖动态
头条新闻
每日新帖
最新热帖
新闻存档
热帖存档
文学城
虎扑论坛
未名空间
北美华人网
北美微论坛
看帖神器
登录
← 下载
《看帖神器》官方
iOS App
,体验轻松追帖。
How to gracefully rollback operations on error?
查看未名空间今日新帖
最新回复:2020年11月12日 7点34分 PT
共 (7) 楼
返回列表
订阅追帖
只看未读
更多选项
阅读全帖
只看图片
只看视频
查看原帖
s
somehow
大约 4 年
楼主 (未名空间)
const doWork = async =() =>
{
try {
await 3rdParthService.step1();
await 3rdParthService.step2();
await mysql.insert(table1);
await mysql.insert(table2);
await mysql.insert(table3);
} catch (e) {
......
}
}
try block里面的任何一步都可能出错,那么catch block应该怎么写比较好?
p
pptwo
大约 4 年
2 楼
你先想明白做到一半停电怎么办,然后再做rollback就容易了。
【 在 somehow (一般宁静) 的大作中提到: 】
: const doWork = async =() =>
: {
: try {
: await 3rdParthService.step1();
: await 3rdParthService.step2();
: await mysql.insert(table1);
: await mysql.insert(table2);
: await mysql.insert(table3);
: } catch (e) {
: ......
: ...................
s
somehow
大约 4 年
3 楼
想不明白
【 在 pptwo (pp) 的大作中提到: 】
: 你先想明白做到一半停电怎么办,然后再做rollback就容易了。
T
TeacherWei
大约 4 年
4 楼
我感觉你把party写错了。
你这是Distributed transaction 吧?
而且我也没看到有 Trans 相应的调用啊。
我建议要不就算了。毕竟,most of the time, it works.
f
fantasist
大约 4 年
5 楼
哪些操作需要rollback?如果只是mysql,用transaction就行
s
sanwadie
大约 4 年
6 楼
分布式交易是比较复杂的,没有简单的方法。如果是Java代码,国内的阿里和华为都给出了自己的开源方案,可用性都还不错,性能吗,你知道的,Java就是靠堆机器。如果自己搞定,可以借鉴他们。
目前有两种方法可以借鉴:
1)可以弄个简单的全局 Transaction Manager,说穿了就是联动commit:通过某种机
制,先完成所有数据库的写,然后一起commit,如果有一个失败,就全部rollback。这个方法改动比较大,是传统数据库two phase commit的分布式实现,并且对infra的稳
定性、可靠性、性能要求高,本身性能(单个交易)比较差,全局 TM需要解决spof
2)补偿方式:对前面的两个svc 建立对应的补偿接口,如果本地数据库修改失败,调
用补偿接口进行反向修改。但这个方式显然不是完美的,在业务逻辑上需要仔细考虑,避免补偿失败。优点:改动小,对硬件,尤其是网络要求低,可以堆机器实现很高的吞吐。缺点:单个交易时间很长,业务逻辑和补偿机制兼容。
另外,如果svc是第三方的,无法修改代码来进行实时补偿或使用全局TM,那么需要在
本地记录全部交易,对失败交易进行事后补偿。总之,先保证所有的交易(成功或失败)都有本地记录,就可以进行实时或事后的rollback,达到所谓的最终一致性
再分享一点自己项目里进行分布式交易的经验:
1) 尽量不要用分布式交易
2)尽量松耦合,让业务逻辑可以做到最终一致性,这样就可以实现事后补偿,实际上
这也是常见的情况,国内所有的大厂的大应用(支付宝、淘宝,京东,银联)都是使用这种方式
3)如果允许,且需要高吞吐,尽量使用补偿方式
4)我们只对和钱有关的个别交易做分布式二阶段提交
T
TeacherWei
大约 4 年
7 楼
赞一个。这位一看就知道是干过的!
当初12306辩论,要是有几位有这个见识的,也不会搞得一地鸡毛。
【 在 sanwadie (三娃爹) 的大作中提到: 】
: 分布式交易是比较复杂的,没有简单的方法。如果是Java代码,国内的阿里和华为都给
: 出了自己的开源方案,可用性都还不错,性能吗,你知道的,Java就是靠堆机器。如果
: 自己搞定,可以借鉴他们。
: 目前有两种方法可以借鉴:
: 1)可以弄个简单的全局 Transaction Manager,说穿了就是联动commit:通过某种机
: 制,先完成所有数据库的写,然后一起commit,如果有一个失败,就全部rollback。这
: 个方法改动比较大,是传统数据库two phase commit的分布式实现,并且对infra的稳
: 定性、可靠性、性能要求高,本身性能(单个交易)比较差,全局 TM需要解决spof
: 2)补偿方式:对前面的两个svc 建立对应的补偿接口,如果本地数据库修改失败,调
: 用补偿接口进行反向修改。但这个方式显然不是完美的,在业务逻辑上需要仔细考虑,
: ...................
请输入帖子链接
收藏帖子
const doWork = async =() =>
{
try {
await 3rdParthService.step1();
await 3rdParthService.step2();
await mysql.insert(table1);
await mysql.insert(table2);
await mysql.insert(table3);
} catch (e) {
......
}
}
try block里面的任何一步都可能出错,那么catch block应该怎么写比较好?
你先想明白做到一半停电怎么办,然后再做rollback就容易了。
【 在 somehow (一般宁静) 的大作中提到: 】
: const doWork = async =() =>
: {
: try {
: await 3rdParthService.step1();
: await 3rdParthService.step2();
: await mysql.insert(table1);
: await mysql.insert(table2);
: await mysql.insert(table3);
: } catch (e) {
: ......
: ...................
想不明白
【 在 pptwo (pp) 的大作中提到: 】
: 你先想明白做到一半停电怎么办,然后再做rollback就容易了。
我感觉你把party写错了。
你这是Distributed transaction 吧?
而且我也没看到有 Trans 相应的调用啊。
我建议要不就算了。毕竟,most of the time, it works.
哪些操作需要rollback?如果只是mysql,用transaction就行
分布式交易是比较复杂的,没有简单的方法。如果是Java代码,国内的阿里和华为都给出了自己的开源方案,可用性都还不错,性能吗,你知道的,Java就是靠堆机器。如果自己搞定,可以借鉴他们。
目前有两种方法可以借鉴:
1)可以弄个简单的全局 Transaction Manager,说穿了就是联动commit:通过某种机
制,先完成所有数据库的写,然后一起commit,如果有一个失败,就全部rollback。这个方法改动比较大,是传统数据库two phase commit的分布式实现,并且对infra的稳
定性、可靠性、性能要求高,本身性能(单个交易)比较差,全局 TM需要解决spof
2)补偿方式:对前面的两个svc 建立对应的补偿接口,如果本地数据库修改失败,调
用补偿接口进行反向修改。但这个方式显然不是完美的,在业务逻辑上需要仔细考虑,避免补偿失败。优点:改动小,对硬件,尤其是网络要求低,可以堆机器实现很高的吞吐。缺点:单个交易时间很长,业务逻辑和补偿机制兼容。
另外,如果svc是第三方的,无法修改代码来进行实时补偿或使用全局TM,那么需要在
本地记录全部交易,对失败交易进行事后补偿。总之,先保证所有的交易(成功或失败)都有本地记录,就可以进行实时或事后的rollback,达到所谓的最终一致性
再分享一点自己项目里进行分布式交易的经验:
1) 尽量不要用分布式交易
2)尽量松耦合,让业务逻辑可以做到最终一致性,这样就可以实现事后补偿,实际上
这也是常见的情况,国内所有的大厂的大应用(支付宝、淘宝,京东,银联)都是使用这种方式
3)如果允许,且需要高吞吐,尽量使用补偿方式
4)我们只对和钱有关的个别交易做分布式二阶段提交
赞一个。这位一看就知道是干过的!
当初12306辩论,要是有几位有这个见识的,也不会搞得一地鸡毛。
【 在 sanwadie (三娃爹) 的大作中提到: 】
: 分布式交易是比较复杂的,没有简单的方法。如果是Java代码,国内的阿里和华为都给
: 出了自己的开源方案,可用性都还不错,性能吗,你知道的,Java就是靠堆机器。如果
: 自己搞定,可以借鉴他们。
: 目前有两种方法可以借鉴:
: 1)可以弄个简单的全局 Transaction Manager,说穿了就是联动commit:通过某种机
: 制,先完成所有数据库的写,然后一起commit,如果有一个失败,就全部rollback。这
: 个方法改动比较大,是传统数据库two phase commit的分布式实现,并且对infra的稳
: 定性、可靠性、性能要求高,本身性能(单个交易)比较差,全局 TM需要解决spof
: 2)补偿方式:对前面的两个svc 建立对应的补偿接口,如果本地数据库修改失败,调
: 用补偿接口进行反向修改。但这个方式显然不是完美的,在业务逻辑上需要仔细考虑,
: ...................