前段时间工作中,有客户反应了系统中某类待办重复出现两次的情况。我核实了数据之后,分析认为是并发请求下导致的数据不一致性问题,并做了重现。其实这并不是一个需要频繁调用的功能,但是客户连续点击了两次,导致出现了并发问题。除了前端优化,这里重点探讨后台方面代码层面的处理,最终解决问题。

一、情景分析

Asp.net程序部署Web服务,是多主线程并发执行的,当多个用户请求进入同一个后台函数时,后进入的请求有可能会获取到非最新状态的数据。

结合我遇到的实际情况举个例子,假设后台函数Func1,先读取表TableA,TableB的数据,进行处理后,存入TableB中,而数据库事务执行会在函数结束前才提交。请求Req1执行Func1提交事务之前,Req2又进入Func1并读取了TableA,TableB的数据,这时Req1执行完成,这就相当于Req2拿到的已经是旧的数据,在旧的数据的基础上再做数据处理操作,结果自然不正确了。

说到这里,你可能还不能想象具体会出现什么问题,而确实这种并发情况在非幂等功能下才会导致数据错误,下面就举实例说明。

二、实例重现

现在有数据表Info,Info2,Info2的数据就是基于Info表数据产生的,两个表都有字段-证件号码IdentNo。

函数SyncWork()的功能为:

1,读取Info表和Info2表中共同的IdentNo行数据,将Info表中的其它字段同步到Info2表;

2,读取Info表中有,而Info2表中没有的IdentNo行数据,将这些数据插入Info2表。

表实体代码实现如下:

Asp.net并发请求导致的数据重复插入问题
 1     /// <summary>
 2     /// 信息表
 3     /// </summary>
 4     public class Info
 5     {
 6         public int Id { get; set; }
 7         /// <summary>
 8         /// 证件号码
 9         /// </summary>
10         public string IdentNo { get; set; }
11         /// <summary>
12         /// 姓名
13         /// </summary>
14         public string Name { get; set; }
15         /// <summary>
16         /// 爱好
17         /// </summary>
18         public string Hobby { get; set; }
19         /// <summary>
20         /// 备注信息
21         /// </summary>
22         public string Bz { get; set; }
23     }
24 
25     /// <summary>
26     /// 信息表2
27     /// </summary>
28     public class Info2
29     {
30         public int Id { get; set; }
31         /// <summary>
32         /// 证件号码
33         /// </summary>
34         public string IdentNo { get; set; }
35         /// <summary>
36         /// 姓名
37         /// </summary>
38         public string Name { get; set; }
39         /// <summary>
40         /// 爱好
41         /// </summary>
42         public string Hobby { get; set; }
43         /// <summary>
44         /// 创建时间
45         /// </summary>
46         public DateTime CreateTime { get; set; }
47         /// <summary>
48         /// 最后修改时间
49         /// </summary>
50         public DateTime? UpdateTime { get; set; }
51         /// <summary>
52         /// 评分
53         /// </summary>
54         public int? Score { get; set; }
55     }
View Code

相关文章:

  • 2022-03-03
  • 2022-12-23
  • 2021-06-29
  • 2022-12-23
  • 2021-08-23
  • 2021-06-20
  • 2021-11-19
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-07
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案