有没有不使用存储过程的方法?????因为对数据库处理,不需要考虑效率方面的问题啊,有存储过程有点麻烦关键是能否在用dataset修改的时候,把数据库的相关记录给锁住,使其它进程无法对其进行修改

解决方案 »

  1.   

    修改->请求->计时->超时重发->N次提示出错
      

  2.   

    引用:使用单线程,给数据库加锁
    -------------------------------------------------------------------------
    在网络上,无法确保没有第二个人执行同样的操作,第一个人的操作出错啊。我也想给数据库加锁,确保第一个人操作成功,第二个人在操作前就提示错误。 问题是锁该怎么加????
    -------------------------------------------------------------------------
    引用:修改->请求->计时->超时重发->N次提示出错
    -------------------------------------------------------------------------
    在数据fill进dataset后,在updata之前,如果有另一个进程修改数据,那么updata一定不成功。 重试100次,结果仍然是不成功啊
    -------------------------------------------------------------------------谢谢大家的关注,希望能有解决的办法。  等。。
      

  3.   

    1、明天去公司我再给你想想加锁的问题
    2、修改->请求->计时->超时重发->N次提示出错
    -------------------------------------------------------------------------
    在数据fill进dataset后,在updata之前,如果有另一个进程修改数据,那么updata一定不成功。 重试100次,结果仍然是不成功啊
    -------------------------------------------------------------------------
    这个是在加锁的前提下,如果有进程操作就要上锁的
      

  4.   

    在SQL SERVER中SERVER对锁的管理十分复杂。在程序中可分为乐观锁和悲观锁。乐观锁就是认为不会有并发现象发生,只在出现并发错误后,才进行处理。这主要通过SERVER中对表中加入一个TIMESTAMP类型列来完成。可用一个函数进行判断在更新时,记录有无被别人修改。另一种就是悲观锁,就是在用记录之前把记录锁住。在SERVER中发出INSERT,UPDATE这些更新语句后,只要不进行COMMIT,那么记录始终维持被独占加锁的状态。也就是说,只要更新不提交就加锁,提交就解锁。方法1:set identity on ,sql server自动进行对序号的管理
    方法2:建立一个表identity,set autocommit off,该表有两个字段,第一个字段表示当前能得到的最大的可用id,第二个字段为表名。
    每次想向表中插入记录时从identity表中得到id(select);将identity表id+1(update);commit;
    然后用得到的id插入你想要插的表
      

  5.   

    Oracle中利用SELECT的FOR UPDATE子句实现给记录加锁conn system/manager--创建实验用户
    grant connect,resource to test identified by test;conn test/test--创建实验表1
    create table a(a number);
    insert into a values(1);
    commit;select * from a for update;

    select * from a for update of a.a;(a表的a列)--新打开一个SQL*Plus窗口
    conn test/test(test用户上的第二个会话)
    delete from a;此时,系统停顿状态,等待解锁,
    只要在第一个窗口发出roll;或commit;命令,即可解除锁定状态。
      

  6.   

    这个对SQLServer事务锁有详细的说明
    http://www.chinaitlab.com/www/news/article_show.asp?id=6123
      

  7.   

    给你个思路做参考:
    1、把对dataset比较耗时间的操作放在事务之外;
    2、设计数据库表的关键字段(可以为自增一;或自定义一个存储过程之类的在修改dataset时就先把字段值存入数据库中,防止多人抢号);
    3、最后以事务提交dataset,失败了不必重置dataset,多提交几次就成。
      

  8.   

    to 可乐:谢谢可乐兄的耐心解答,我用的正是sqlserver。你提供的网址正在看。to 土豆:
    1、如果最终本问题无解,我会使用ExecuteNonQuery()方法来解决。2、设计数据库表关键字段的方法,感觉不是百分之百的安全。 如果一个进程在锁定记录后,进程出现异常关闭(机率小,但是很难杜绝),则又是一个麻烦事。3、不必重置dataset,多提交几次就成。 我已经试过了,如果在fill和updata之间,数据库被改变了,则不管updata多少次,结果都是一定不成功
    谢谢大家的关注,继续研究这个问题。 希望能有解,毕竟,用dataset来updata,比用一大堆ExecuteNonQuery()要直观一些,用起来也要爽一些。现在并未实际做程序,只是先对操作数据库的各种方法,做一个比较全面的了解。谢谢大家了
      

  9.   

    已经测试出一种解决办法了,通过先对表执行一个updata操作,取得独占锁。 这样,第二个进程在执行updata操作时,就会出错。 代码修改如下:以前的代码:OleDbCommand cm=conn.CreateCommand();
    cm.CommandText="select * from aTable";
    cm.Transaction=trans;
    OleDbDataAdapter ad=new OleDbDataAdapter(cm);
    OleDbCommandBuilder builder = new OleDbCommandBuilder(ad);
    DataSet ds=new DataSet();修改后的代码:
    OleDbCommand cm=conn.CreateCommand();
    cm.Transaction=trans;
    try
    {
      cm.CommandText="update aTable set f3=f3";  //一个不影响数据库数据的updata操作
      cm.ExecuteNonQuery();
    }
    catch(Exception ee)
    {
      trans.Rollback();
      cm.Dispose();
      conn.Dispose();
      return;
    }
    cm.CommandText="select * from aTable";
    OleDbDataAdapter ad=new OleDbDataAdapter(cm);
    OleDbCommandBuilder builder = new OleDbCommandBuilder(ad);
    DataSet ds=new DataSet();这种方法,多了一个对表的ExecuteNonQuery()操作,效率上应该不会有太大的影响。但是,在多进程情况下,应该可以确保安全。以上代码,已经测试通过。问一下DX们,这种解决方式如何??? 有没有缺陷或不合理的地方?????谢谢
      

  10.   

    你开始的方法是对的,  你的第二种方法将整张表都锁定住了。 在你执行 ExecuteNonQuery()后 别人都处于等待状态了,  要等你完成 update 后别人才能做。  怎样你的事务时间太长了。  你要做的就是尽量压缩你的处理时间。
      

  11.   

    另外如果你可以容受在别人提交后, 你将你修改的数据覆盖。  你可以重新写一个updatecommand。 主要是重新写它的where 条件  只要按照主键来过滤就行。   commandbuilder 默认的是将每一个字段旧的值都作为where条件。  如果别人修改了某条记录的某个字段,  当然你在提交这条记录时就会出现更新0条记录的情况, 这个时候就出错了。 在实际应用的时候一般都不会用那个commandbuilder来做,  需要你自己来写相应的insertcommand, updatecommand, deletecommand
      

  12.   

    回蜀人:我们做一个假设条件,两个用户,这里简称A和B。 假设A用户先执行这个操作,而B用户在A用户执行完之前,也申请修改A用户正在修改的数据记录两种情况情况一: A用户修改数据要花费2秒钟如果A用户不锁定记录,执行效果如下:
    1、A读取完数据,并在dataset中做修改操作
    2、B在A进行修改的时候,申修改A正在dataset中作修改操作的数据。由于A未加锁,申请成功,并修改
    3、A用户通过adapter将dataset的数据回写到数据库中的时候,报错。在这种情况下,必须做异常处理,也就是说要把数据修改重新做一次。
    4、在A处理异常,重新作修改的时候,在极端情况下有可能用户B再次修改数据,则再次回到第3步。如果A用户锁定记录,执行效果如下:
    1、A读取完数据,并在dataset中做修改操作
    2、B在A进行修改的时候,申修改A正在dataset中作修改操作的数据。由于A加锁,则B自动进行等待
    3、A通过adapter将dataset的数据回写到数据库,成功。 并同时解除锁定
    4、B在A解除锁定后(等2秒),自动完成了修改操作。整个执行过程中,没有异常情况二: A用户修改数据要花费10分钟如果A用户不锁定记录,执行效果如下:
    1、A读取完数据,并在dataset中做修改操作
    2、B在A进行修改的时候,申修改A正在dataset中作修改操作的数据。由于A未加锁,申请成功,并修改
    3、A用户通过adapter将dataset的数据回写到数据库中的时候,报错。在这种情况下,A花费10分钟做的工作,已经报废了。如果让A用户重新作这个花费10分钟的操作,A用户只能骂人如果A用户锁定记录,执行效果如下:
    1、A读取完数据,并在dataset中做修改操作
    2、B在A进行修改的时候,申修改A正在dataset中作修改操作的数据。由于A加锁,则B自动进行等待
    3、由于A锁定时间太长,B用户等待超时,报错(通知B用户有人正在对数据库做全盘调整,请稍后再试)
    4、10分钟后,A用户通过adapter将dataset的数据回写到数据库中的时候,成功
    5、10分钟后,B用户再次申请修改数据,成功(注:B用户可能会在10分钟以内做多次尝试)回蜀人:
    为个问题,还没有做个实验,可以探讨一下
    假设修改10000条记录。
    方法一:执行10000次updatacommand操作,完成修改
    方法二:将10000条记录,查询入dataset,修改完成后,再一次性updata写回数据库两种方法,哪种效率更高????  在效率上会不会有N倍以上的差异????