浅谈ADO.NET文章系列之二 — 并发更新冲突的处理

ado

声明:这里只对并发冲突做简单的分析,所以在前面冠以“浅谈”二字,希望大家可以从中看到一般的处理方法和注意的事项,如果有什么疏漏,那也相当地自然,毕竟本人水平有限,还有很多需要提高的地方,希望各位朋友不吝指正!
一.为什么会产生并发在我们使用ado.net对数据库中数据进行操作时,很有可能这种操作或类似地操作也在网络内其他用户中进行着,那么就难以避免地会遇到更新操作失败的情况。因为为了更好地提高性能,ado.net采用了断开连接的方式。也就是说要先把数据的副本读取到客户端,那么也容易引起多个用户同时更新一条记录产生数据并发异常。这个操作,很可能是其他用户删除了该行记录,也可能是修改了某个字段。这个问题是个高级话题,也一直是数据操作中的难点。在下面我只做简单地讨论和分析。二.解决方案通常处理并发冲突的方法有两个。一个是保守式并发处理,一个是开放式并发处理。所谓的保守式并发处理,就是使用锁使某条记录被读出后就一直被锁定,直到该用户提交更新。它的坏处正如它的名字一样,相当地保守。因为如果该用户读完该条数据后就因为有事情而离开或者忘记了来点“更新”操作,那么其他用户要一直等待,直到他回来或者被提醒或者自己想起来。很明显,这不是我们想要看到的(当然,在特定的要求和条件下该方法也有它的优点,否则它也没有存在的必要了)。相反,开放式并发是我们所要讨论的重点,这个也是ado.net推荐使用的方法。什么是开放式并发处理方法呢?我自己的理解就是要面对并发异常的出现,制定处理方法来解决或者提示用户这种异常的出现。既然并发不可避免,那么我们就要作好处理并发冲突的解决方案。这就象一个乐观的人一样,他有了疾病,他的心态依然是乐观向上的一样,他要把重点放在如何治疗上而不是彻底地避免(这个比喻可能不太恰当,见笑了!呵呵)。在写程序前要考虑到并发出现的可能,根据自己的需要来选择更新逻辑和方式。三.浅论开放式并发处理的要注意的地方。(这里也是最容易引起问题的地方,大家要多提意见啊!)

 1.  更新方式的选择  一般来说,更新方式有缓存更新和立即更新两种。缓存更新,就是使用dataadapter.updte()方法来进行数据的更新。我们可能在datagrid中修改了很多记录,而只进行一次提交,那么这种操作如果从读取数据开始(或上次更新操作)算起所距离的时间越长,也就越容易引起并发冲突。相对来说,立即更新,也就是使用command.executenoquery()方法,直接来提交对一条记录的修改应该比较快捷,但仍然不能完全避免冲突的出现,但仍然是我推荐的方式。2.  更新逻辑的选择  更新逻辑:我理解的就是按照哪种更新的方式来对数据进行更新操作。它可以是包含所有列的;可以是只包含主键列的;可以是包含主键列和被更新列的;可以是包含主键列和时间戳列的。我们来看这4中更新逻辑的差异。如果你以前用过Pb来进行编程,那么可能你理解起来就相对容易。因为pb里面的三种更新逻辑和这里的有很多相似的地方。为了更好的说明问题,我们来举一个例子。有表 table1( id,name,sex,address,salary,tamp) 其中的tamp是时间戳列。那么对应的更新逻辑为:(1)                 update table1 set id=?,name=?,sex=?,address=?,salary=? Where id=? And name=? and address=? And salary=? (2)                 update table1 set id=?,name=?,sex=?,address=?,salary=? Where id=?(3)                 update table1 set id=?,name=?,sex=?,address=?,salary=? Where id=? And name=? (这里假设只对name列进行修改,而其他列不变)(4)                 update table1 set id=?,name=?,sex=?,address=?,salary=? Where id=? And tamp=?     我们来对这4中逻辑进行简要的说明:第1种也是默认地一种,把所有的字段都包含进去,那么当有用户A ,B读取了数据后,A成功更改了一行记录中的name,那么如果B再要更改同行记录时,由于WHERE条件中要求满足所有的字段,而这个时候NAME已经改变了,这样他将更新失败。对于第2种方法,它只包含主键,那么也就是说如果不修改主键(或删除)(修改主键是危险的,应该避免!)的话,都会成功,但A更新成功了,B也更新成功了,但B的更新覆盖了A的更新,这个时候B甚至不知道原来自己更新的时候记录已经有了变化,A也不知道自己的记录已经被覆盖。这种方法也叫做“后来居上”的方式。也就是后面的覆盖前面的操作。这里也说一句,我一般采用该种方法,但不是说它有多好,而是为了快速开发。第3种方法,既包含主键也包含更新的字段。假设A成地更新了一条记录的NAME字段,B更新该行记录的SEX字段,那么B也会成功的实现自己的更新。但同样,如果没有刷新显示的话,他们都不知道该行记录的对应字段发生了变化。在PB里,这种方式是被提倡使用的。但在.NET里这种方式的构建相对来说比较麻烦,写的代码也比较多,是种比较消耗时间和精力的。对于最后一种方式,它采用了时间戳列作为更新条件,时间戳能反映记录更新的变化。如果时间戳变化了,那么该记录自然已经被别人更新过了。这种方法是这里推荐的方法。当然每种更新逻辑都有自己的好处,我们也不能特意地使用哪种,要根据自己的系统的情况来选择。一般来说,第1种方式是dataadapter默认生成的,而第2种,第3种,第4种都要我们自己来设置。手动地创建更新逻辑(就是指定对应的insertcommand的commandtext和updatecommand的commandtext和deletecommand的commandtext)是个费时费力的过程,但更新效率也相对较高。

 

 3.  更新逻辑产生的说明  如果更新逻辑是使用dataadapter的向导来产生的,那么可以在高级选项里把“使用开放式并发”的复选框去掉。这样将实现使用这种更新策略。对于那些只是设定dataadapter的selectcommand.commandtext而使用commandbuilder的构造函数来生成(或使用相关的getupdatecommand等方法)更新逻辑的程序,这里建议不要这么做,虽然这样比较方便,但也为更新时的效率和可控制性打了折扣。希望大家注意,不到万不得以,不要使用。4.  如果更新方式和更新逻辑都选择好了以后,那么就要考虑使用事务了。在事务中进行更新操作的结果就是要么全部成功,要么都不成功。简单地说就是“要么全做,要么不做(呵呵,记得刚毕业在济南工作的时候,项目组长问我,我就是这么回答的!)所以使用事务的程序代码是比较安全的。类似如下的代码:

Dim mytransaction As oledbTransaction

            Try

                conn.Open()

                mytransaction = conn.BeginTransaction

                cmd1.Transaction = mytransaction ‘这里假设已经建立了cmd1对象

                cmd1.ExecuteNonQuery()  

                mytransaction.Commit() '提交事务

 

         Catch ex As Exception

                mytransaction.Rollback() '回滚事务

                Return -1 ‘做一些其他处理

         Finally

                conn.Close()

   End Try

 

  说明:对于dataadapter.update方法,如何使用事务呢?其实dataadapter本身并不进行数据更新,而是它的insertcommand,updatecommand,deletecommand。那么就象上面一样设置这三个command对象的Transaction属性就可以了。其他的和上面没有什么不同。

 5.  既然我们在前面说了采用开放式并发处理,就要对异常进行相应的捕获,给出相应的提示信息和处理办法。对于那些可能引起异常的代码都要包含在try     …  end try 块之间,这是一个很好的习惯。一般可以采用类似下面的操作:

Try

            Sqldpr1.Update(ds1.Tables("table1"))

 Catch Ex As Data.DBConcurrencyException '并发冲突的异常

     ‘做相应的处理  End try 说明:这里的做相应的处理,可以是把最新的行从数据库中读出来更新现有的行(当然如果该行被删除例外),也可以重新填充数据(fill操作)。这个时候我们可以作出判断,该行是被删除的情况,可以使用一个函数将Ex.row(“ID”)作为参数传递过去,使用一个command.executeschar方法来判断是否记录存在,使用executereader或fill来取得已经变化的记录或刷新全部记录。这里提到了update()方法引发的异常,如果是立即更新引起的,处理的方式也是一样的。

 总结:  由于时间和本人水平的问题,这个问题不能讨论的太深入,请大家原谅。可能里面涉及的范例代码比较少(呵呵,真的很少),读起来可能有些头疼,但我想如果你对数据更新的原理如果比较熟悉应该可以理解其中的意思。最后,还是希望大家能多提意见!有时间一定给出相关的范例代码。                                

时间: 2025-01-10 03:09:28

浅谈ADO.NET文章系列之二 — 并发更新冲突的处理的相关文章

浅谈VB.NET文章系列之一 --通过例子,浅谈反射(Reflection)的应用

浅谈VB.NET文章系列之一通过例子,浅谈反射(Reflection)的应用说明:应该说这篇短文根本算不上什么深入的分析性的文章,所以在标题前加上了"浅谈"二字,希望对于一般的读者来说,可以给你一个相对直观些的对反射的认识.                                                             --2005/05/23 于东莞在这里对反射以及反射的概念在最后给出简要的解释.一.用来测试的程序集文件的建立.首先你需要建立一个类库文件(编译

浅谈php用户身份认证(二)

                  浅谈php用户身份认证(二)                              爆米花 2001年12月28日 www.westxj.net(二)基于http的多用户验证    上次给大家介绍了基于http的单用户验证,这次利用mysql数据库储存多用户数据,进行多用户验证.1.首先建立mysql数据库mysql>create database user;        //建立数据库usermysql>use user;              

浅谈如何写文章的标题

浅谈如何写文章的标题 首先,软文标题要抓特色,抓主要关键词 我在创建关于一篇站长百科网站推广的软文标题时,我考虑到站长百科是一个关键词,但太热,不容易被搜索引擎亲睐.由于自己也是一个站长,所以我就站在站长的用户角度着眼,想一下一般的站长朋友会怎么搜,自己平时又是如何搜的,希望得到怎样的结果,经过深入思索与分析,我认为,做为一个想搜索站长百科站点的用户,肯定是想搜到一个既然全面又在业内普遍欢迎的站点,于是我确定了"站长百科第一行业门户网站"为标题,结果百度排名在第一页,带来了有效的流量,

从我个人的经历浅谈伪原创文章

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 我曾经有写过一段伪原创文章的经历,是在网站上做兼职,帮一个网站写的.我们的写作方式主要从网站上自己采集一些文章来,然后自己改动一下.主要改动的方式有那么几点. 第一,改动标题.第二,第一段自己重写大约一百来字,大都是些总结性的文章,或者直接将原文的第一段删除,然后根据原文的意思按照自己的叙述方式去重塑第一段.第三,中间的段落颠倒一下顺序,将一

浅谈ADO.NET与ADO!!

ado 最近老是看到有网友问关于ADO.NET和ADO的区别和好坏问题,想想自己在刚接触.NET时确实也有此疑问,现将我的一点理解和体会写来,希望能对大家有点帮助! 其实大部分东西还是来自MSDN!! ADO 对于用本机代码编写的应用程序,ADO 为 OLE DB 数据提供程序提供基于 COM 的应用程序级别接口.与 ADO.NET 相似,ADO 支持各种开发需要,包括使用与关系数据库和其他存储区中的数据的活连接来创建前端数据库客户端和中间层业务对象.而且,像 ADO.NET一样,ADO可构建客

浅谈站内文章编辑的基本要点

近来和很多站长朋友聊天的时候,大家都提到站内文章编辑问题,都反映虽然网站已经有一定权重,但是编辑好的文章很多还是没有被收录;有些被收录的文章没有获得相应排名;有了排名跳出率又很高.经过大家讨论得出站内文章以下的编辑要点,仅供参考. 文章排版规范化 排版规范化主要是针对用户体验来说的,一篇有排版的文章明显要好过一些杂乱无章的文章,一个排版规范的文章讲究的是有头有尾有内容,正所谓虎头凤尾猪肚子,很形象的为我们解述了文章基本的排版标准. 网页颜色布置合理 也许你会感到不解,文章的质量和颜色有什么关系,

浅谈如何提高文章质量的四个技巧

现实生活中,我们都希望能够买那些物美价廉的产品.一方面,产品的包装可以满足人们的心理需求.另一方面,还可以用最低的价格买到自己想要的东西.可是,我们却忽略了最重要的一点,就是我们使用产品的时间,也就是我们能够对这件产品的质量如何.这一点没有考虑到.质量才是一个产品的生命,没有质量,便没有保证.无论任何东西,基本可以通过外在来发现产品的好与坏.同样的道理,一个网站的文章,是否对用户带来一定的实际价值,才是关键点.下面就是我对文章质量的一些总结,希望对你们有帮助. 第一:立意深远,启人深思. 每个人

浅谈什么样的文章适合网络推广

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 网络推广,可谓是手段繁多,花样迭出,无论是哪种方法,都有其值得称道之处,可在众多推广手段中,我唯独对软文推广情有独钟,最为偏爱!当然,这并非代表我对其他的手段不看重,只是龙有其首,狼有其王,个人认为,在众多推广手段中,软文推广的作用应当排名第一. 也许有朋友看到此论调之时,或大为不满,斥之为异论,但今日只为阐述自己的一份见解,便不来讨论这软文

网络推广 浅谈网络推广文章如何写

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 写推广文章首先要明白出发点,我们的目的是排名,一切不以排名为目标的文章,都是不合格的文章. 一.标题 标题对排名影响最大,强调标题的重要性,是因为同样的文章,好的标题会排名很好,标题则可能没有多好的排名. 标题一般写法:关键词+短句. 短句的写法要点: 1.短句的内容要出现关键词分词. 神马是分词?中文分词技术是搜索引擎的核心,我这里讲的分词