并发条件下,数据更新丢失解析

来源:互联网 发布:linux编辑器 编辑:程序博客网 时间:2024/05/01 21:22
某天小美收到配送员投诉电话:我的配送费打少了!我今天配送了10单,每单10元,却只给我打了80元!单笔配送费的计算过程是这样的:每个配送员对应一个账户,此有账户“id”和余额“balance”两个属性。当配送员完成一单配送时,此账户的余额=当前余额+此单配送费。(具体的数据更新过程见图1)整个计算过程是在一个事务里,过程简单明了,为什么会出现配送费计算出错的问题呢?图2是并发场景,并发事务1的结果被并发事务2的结果给覆盖了!正确的结果是最终配送费为15。1数据更新丢失结合上面的例子,数据更新丢失指的是当两个和两个以上事务选择同一记录,基于最初选定的记录值更新该记录时,会发生丢失更新。每个事务都“不知道”其它事务的存在,最后的更新将重写由其它事务所做的更新,这将导致数据丢失。2解决之道使用SELECT XXX FROM XXXX FOR UPDATE:对符合查询条件的行加写锁,见图3按照FOR UPDATE的语义,在同样的并发场景下,并发事务2在执行“SELECT balance FROM account WHERE id=1 FOR UPDATE”时会一直等待并发事务1提交释放了该行的写锁之后,才继续执行。因此,使用对行加写锁的方式解决了数据的更新丢失问题,见图4。3慧眼识之• 分析业务场景中是否存在对同一记录进行“先查询,后更新”的操作。保守点说,业务是否支持并发处理。
• 构造此场景,对该场景进行并发测试举个栗子,商户转账时,存在多个业务请求对同一商户进行转账的情况,此时商户余额的修改是否正确需要进行并发控制。以Transfer接口为例,对同一商户进行并发转账测试:4未雨绸缪根据功能需求抽象出事务后,需重点分析事务及其内部包含的读写sql语句在并发场景下是否会出现功能正确性问题。常见的事务并发场景:• 同一事务运行在多线程的场景,每个线程有其对应的一个事务实例,同一事务不同的实例构成了并发场景• 不同的事务A和B运行在多线程的场景中,事务A在一个线程中,事务B处于另一个线程中,处于不同线程的不同事务构成了并发场景。
影响事务并发正确性的常见因素包括事务的隔离级别、sql语句对应的锁。这两者相互结合保证事务并发的正确性,来避免以下常见的4种事务并发问题:1.脏读2.不可重复读3.幻读4.更新丢失故在分析事务并发正确性时要重点关注事务的隔离级别是什么,sql语句是否会加锁,锁是什么
在确定好哪些事务会构成并发场景以及事务中使用了哪些锁之后,可以根据这些信息画出并发场景下两个事务或不同的事务实例执行序列图(见图4),以此分析事务并发问题。
0 0
原创粉丝点击