首页 新闻 会员 周边 捐助

ASP.NET Web API 如何实现超时回滚所有操作

0
悬赏园豆:100 [待解决问题]

请教大家,项目为 .NET Framework 4.6.1,ASP.NET Web API 2,数据库操作使用 Entity Framework,数据库为 SQL Server 2008 R2 以上。

有这种场景,Web API 有一个协议会往同一个数据库的多个表中写入信息。

正常情况下是很快的,但有时候会有一些大查询或者批量导入发生在这个协议使用的表中。由于大查询、批量导入会给这些表加锁。

如果正好有大查询、导入任务执行时,访问该 API 协议,可能无法在几秒内返回。导致调用方那边已经到超时时间,给出了提示,但 Web API 还在执行相关插入任务,并且等锁释放后,数据还会插入成功。

请问有什么办法,能在 Web API 中,为个别或所有的 Action 加上超时时间,当到达这个时间后,终止当前进行的操作并回滚?

  • 我考虑过通过 transaction scope,但这样需要开一个很大的事务,这个事务里既有查询又有INSERT或UPDATE,与事务应该尽可能小相悖

  • 我明白问题的根本不在这,但需要有这样一种防御机制。一旦出现这种问题,需要能尽量避免

谢谢。

huhubun的主页 huhubun | 初学一级 | 园豆:102
提问于:2020-08-14 12:05
< >
分享
所有回答(6)
0

双方调整超时时间(每一个网络环节都有设定);

如果时间很久,可以做成任务,一个接口发起任务,一个接口查询任务状态;

办法很多根据自己场景适用选择即可。

花飘水流兮 | 园豆:13615 (专家六级) | 2020-08-14 13:50

谢谢回答~

做两个接口,一个用于发起操作,一个用于查询操作状态这个因为涉及到调用方的修改,不太能推进

现在更希望是,假设调用方都是20s超时,我就让 web api 里所有操作10s内完成不了就回滚,并给调用方返回错误信息

支持(0) 反对(0) huhubun | 园豆:102 (初学一级) | 2020-08-14 14:03

@huhubun: 那这不更简单,计时定时,记录操作。但你http api服务端和客户端需要设定超时时间比如15s。

支持(0) 反对(0) 花飘水流兮 | 园豆:13615 (专家六级) | 2020-08-14 14:06

@花飘水流兮: 计时可以,但怎么做到时间到了回滚呢

支持(0) 反对(0) huhubun | 园豆:102 (初学一级) | 2020-08-14 14:53

@huhubun: 可以终止的函数那么终止(检查结果决定step),不能终止的就等待执行结果并记录step;

有正序执行step,那么反序去恢复现场即可(过程根据场景需要 比如失败尝试n次等等,机器永远没有100%的保障,只能尽可能保障,比如函数执行一半,断电连ups都坏了,如果不坏,运营、运维以及开发的失业人员也就更多了)。

支持(0) 反对(0) 花飘水流兮 | 园豆:13615 (专家六级) | 2020-08-14 17:55
0

写数据接口收到数据,返回处理中,写入队列处理,
查询状态接口,返回处理状态,
一个任务处理队列中的数据。

flyfishing | 园豆:943 (小虾三级) | 2020-08-14 14:44

谢谢回答~

这样需要变更对接流程,不好推动。更希望是在这个协议内部做改动,不知道有没有办法,谢谢。

支持(0) 反对(0) huhubun | 园豆:102 (初学一级) | 2020-08-14 14:52

@huhubun: 你这个不好处理啊。例如 你在Task里边执行,设置个5秒的超时时间。5秒没执行完就取消,取消就回滚事务。也是可以做的,接口请求超时时间就设置的比这个大一些,例如 6秒超时,

支持(0) 反对(0) flyfishing | 园豆:943 (小虾三级) | 2020-08-14 15:00
0

如果你的事务很长了.那你要考虑的不是怎么让这个事务变得不会出问题.
而是该把这个事务拆分开了.

吴瑞祥 | 园豆:29449 (高人七级) | 2020-08-16 02:29
0

1.长耗时的操作API 应当自己控制超时,而不能依赖客户端的超时设置
2.长耗时的操作API,同步的方式是否合理?业务逻辑是否可拆分下,一个http请求至少应当控制在1-2s内。
3.考虑异步回调的方式
a.调用接口申请长耗时操作,接口内部推送消息队列,返回正在处理
b.消费程序消费队列,执行长耗时操作。执行完成(或者超时)回调客户端接口,返回结果。
或者更简单的方式:api接到请求,起一个线程去异步处理。客户端采用轮询的方式,请求是否处理完成及处理结果。(这种方式会有性能和并发影响)

gt1987 | 园豆:1150 (小虾三级) | 2020-08-21 09:03
0

楼上都把更好的方案说完了, 如果现阶段都不太合适用的话, 那就按照你的思路:

  1. 不管是client给的timeout, 还是你server端预设的timeout 都可以.
  2. 恐怕还得transaction scope走起, 但是代码可以调整, 可以把query的部分都完成后,生成所有的update后,一次性trans scope推到db.
czd890 | 园豆:14488 (专家六级) | 2020-08-31 16:12
0

为啥不试下对数据库进行读写分离,主库只写,从库只读

大志若愚 | 园豆:2138 (老鸟四级) | 2020-09-05 12:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册