数据库原理补充:数据库并发控制软件设计案例.ppt

上传人:tian****1990 文档编号:11536435 上传时间:2020-04-27 格式:PPT 页数:24 大小:648KB
返回 下载 相关 举报
数据库原理补充:数据库并发控制软件设计案例.ppt_第1页
第1页 / 共24页
数据库原理补充:数据库并发控制软件设计案例.ppt_第2页
第2页 / 共24页
数据库原理补充:数据库并发控制软件设计案例.ppt_第3页
第3页 / 共24页
点击查看更多>>
资源描述
,并发控制案例分析,主讲:吕震宇,说明,实验环境:VisualStudio.NET2005SQLServer2005其它说明:SQLServer2000+VS.NET2003也可以需要对代码做细微调整源代码及数据库见附件,并发控制案例,设某银行存款帐户数据如下表:现在要求编写一程序,完成两项功能:存款与取款。每次操作完成后向明细表中插入一行记录并更新帐户余额。,1、问题似乎很简单,解决办法:读取最后一行记录的帐户余额数据根据存、取款金额计算出新的帐户余额将新的记录插入表中真的这么简单?在不考虑并发问题的情况下是可行的如果考虑并发,问题就多了,到银行取钱,单位发工资,银行读取帐户余额400元,单位读取帐户余额400元,单位发工资2000元更新帐户余额,取款100元更新帐户余额,余额错误,上述解决办法的并发问题,2、让我来想一想,问题所在:并发问题!解决办法:加锁!在读最后一条记录时先加上锁。怎么加锁?加什么锁?读之前加共享锁?读之前加排它锁?,读之前加共享锁?显然不行!,到银行取钱,单位发工资,银行读取帐户余额400元,单位读取帐户余额400元,单位发工资2000元更新帐户余额,取款100元更新帐户余额,余额错误,读之前加排它锁,事务完成再释放?三级封锁协议中没有定义读前加排它锁(暂且不管)显然不行!,到银行取钱,单位发工资,银行读取帐户余额400元,单位读取帐户余额400元,单位发工资2000元更新帐户余额,取款100元更新帐户余额,余额错误,等待等待等待,还不止这些,如何读取帐户余额?SELECTTOP1帐户余额FROM帐户明细ORDERBY序号DESC存在的问题:在并发场景下你怎么确定它一定是最后一行?随着数据量增大越来越没效率(因为需要排序),3、看来问题真的不是这么简单,问题出在哪里呢?从系统设计一开始我们就走错了!重新设计!,Account,AccountDetail,冗余数据,为什么引入冗余数据?确保帐户余额在唯一的地方进行存储避免了读取帐户余额时访问大量数据并排序新问题:我们无法直接对数据库进行锁操作必须通过合理的事务隔离级别完成并发控制ReadUnCommittedReadCommittedRepeatableReadSerializable,4、着急吃不着热豆腐,看来我们必须对各事务隔离级别逐一分析ReadUnCommitted显然不行在这个事务隔离级别下连脏数据都可能读到,何况“脏”帐户余额数据。ReadCommitted也不行该隔离级别与二级封锁协议相对应。读数据前加共享锁,读完就释放。前面分析过,此处不再赘述。,RepeatableRead这个隔离级别比较迷惑人,需要仔细分析:RepeatableRead对应第三级封锁协议:读前加共享锁,事务完成才释放。例:假设事务1执行存钱操作,首先对帐户余额加S锁,然后修改数据。此时事务2要想改帐户余额,它必须先加X锁(自然加不上),所以无法完成操作。这似乎避免了并发问题的发生,在一个事务执行时将另一个事务的修改请求暂时阻塞,直到事务完成。但真的能满足应用程序的需要吗?,到银行取钱,单位发工资,银行读取帐户余额400元,单位读取帐户余额400元,单位发工资2000元更新帐户余额XLock等待等待等待等待等待等待,取款100元更新帐户余额XLock等待等待等待等待等待等待等待等待等待,尚未提交的脏数据,可见RepeatableRead事务隔离级别容易造成死锁。一旦出现死锁,DMBS不得不牺牲一个进程。牺牲进程换来的是不会出现并发异常。Serializable该事务隔离级别在执行时可以避免幻影读。但对于本案例执行效果与RepeatableRead一样。,5、绝处逢生,似乎走到了绝路连最高隔离级别都会在高度并发时因为死锁造成很大一部分事务执行失败原因分析死锁的原因是因为读前加S锁,而写前要将S锁提升为X锁,由于S锁允许共享,导致X锁提升失败,产生死锁。解决办法如果在读时就加上X锁,就可避免上述问题从封锁协议角度这似乎不可能,但确完全可行!,解决办法:其实SQLServer允许在一条命令中同时完成读、写操作,这就为我们提供了入手点。在更新帐户余额的同时读取帐户余额,就等同于在读数据前加X锁。命令如下:UPDATEAccountSETnewBalance=Balance=Balance+100WHEREAccountID=1上面的命令对帐户余额增加100元(蓝色部分)同时读取更新后的帐户余额到变量newBalance中由于读取操作融入写操作中,实现了读时加X锁,避免因锁的提升造成死锁。,完成存取款的操作可由下面的伪代码实现:,amount=存取款的金额BEGINTRANSACTIONTryUPDATEAccountSETnewBalance=Balance=Balance+amountWHEREAccountID=1INSERTINTOAccountDetail(AccountID,Amount,Balance)VALUES(1,amount,newBalance)COMMITCatchROLLBACK,此处甚至将事务隔离级别设置为ReadUnCommitted都可以,改造结果:通过上述改造,事务中只有写操作而没有了读操作因此甚至将事务隔离级别设置为ReadUnCommitted都能确保成功执行写前加X锁,避免了因提升S锁造成死锁的可能实验结果:所有并行执行的事务全部成功帐户余额全部正确程序执行时间同串行执行各事务相同,6、事情并没有结束,还有可优化的余地网络带宽受到限制时,数据在网络上传输的时间往往比对数据进行读写操作的时间要长。一个典型的更新过程:1、读前加锁2、帐户数据从网上传过来3、修改、插入新记录4、将改后的数据通过网络传回去5、数据库提交更新并解锁。如果网速很慢,资源锁定时间就很长。,解决办法:使用存储过程修改后的更新过程:1、将存、取款用到的数据通过网络发给存储过程。2、数据加锁、修改、解锁。3、将结果通过网络回传。将网络延迟放到了事务之外,提高了事务效率。,实验结果由于在同一台机器上执行数据库与应用程序,实验结果表明存储过程的执行效率不如直接在应用程序中通过命令调用高。如果能在一个带宽受到限制的网络上将数据库与应用程序分离,然后测试,相信会有令人满意的结果。(有待具体实验证实),
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!