SET TRANSACTION ISOLATION LEVEL SERIALIZABLE是为了防止在事务没有完成的时候另一用户,访问事务内,未提交的数据
create table Table1 (a int)
go
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
begin tran
  insert table1 values(1)               ----这句在事物没有commit前,被另一个用户
                                        ----访问是错误的,应为下面有可能会出错  insert table1 values('aaa')           ----这句由于类型不一样将报错
                                        ----设置了SERIALIZABLE的话就不会发生脏读
commit transelect * from table1

解决方案 »

  1.   

    我是作医院管理系统,告诉我结构,我帮你作
    可以参考http://expert.csdn.net/Expert/topic/1605/1605896.xml?temp=.7570307
    可以用游标我
      

  2.   

    可以用游标我 <<== 哈哈打错字了吧
      

  3.   

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    隔离等级太高,是否会影响并发操作?
      

  4.   

    用游标太复杂了吧。我的方案很简单:
    库存量表:orderamount
    ordercode(药品代码)  C6
    amount(库存量)       numeric
    用事务方式做发药:
    select amount from orderamount where ordercode=药品代码  (开始加排他锁)
    if amount>=发药量 then 
       update orderamount set amount=amount-发药量 where ordercode=药品代码
    else
       作缺药处理
    最后commit并解锁
      

  5.   

    对!对于单句 insert update delete 用默认的就OK了
    对与多句的 用 begin tran       commit tran 完全可以搞定 事务问题像楼主这样用
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    就可以避免脏读。(其实在使用中,我也很少用)
    解决死锁的问题最有效的办法就是减少事务代码,减少事务执行时间,千万不要如:
    create proc ...
    as
    begin tran
     .......
     ....
      ....   --这样不死才怪了
     ...
      ...
    commit tran
    go
      

  6.   

    举例:3)死锁
    增设table2(D,E)
    D    E
    d1   e1
    d2   e2
    在第一个连接中执行以下语句
    begin tran
       update table1
       set A='aa'
       where B='b2' 
       waitfor  delay '00:00:30'
       update table2
       set D='d5'
       where E='e1' 
    commit tran
       
    在第二个连接中执行以下语句
    begin tran
       update table2
       set D='d5'
       where E='e1' 
       waitfor  delay '00:00:10'
       update table1
       set A='aa'
       where B='b2'  
    commit tran同时执行,系统会检测出死锁,并中止进程
      

  7.   

    用SET TRANSACTION ISOLATION LEVEL SERIALIZABLE是在存储过程中使用的吧,我想不使用存储过程,在客户端使用select查询库存时就把记录锁住,不允许其他用户对此药品作发药,等到update完了再解锁。
      

  8.   

    你不如在程序里控制,设置一个全局静态信号表量或建立一个加锁解锁表如:create table lock (a varchar(255),b bit)开始发药
      if exists(select 1 from TableNmae where a='XXX' and b=1)
      begin
        select '加锁失败,请稍后重试'
        return
      end
    begin tran
      update lock set b=0 where a='XXX'
      ....
      ...
      update lock set b=1 where a='XXX'
    commit tran
    意思是这个你可以在程序来做!选中Microsoft SQL Servers-->工具栏,工具-->选项-->高级-->查询超时-->改为1000 就是1秒
      

  9.   

    1. 事务中第一个select实际可能就已经所住了记录,而不是等到下一个update语句。
    2. 整个事物确保在“瞬间”可以完成。
    3. 如果中间必须有与客户端交互,重新安排业务流程使事务处理避开客户端交互动作,利用业务领域的对象自身的约束来保持分散化了的事务之间的数据一致性。
      

  10.   

    一下流程是错误的(虽然容易忽视,但是最好现在就引起重视):
    1.查询库存,判断库存是否充足。
    2.begin tran
    3.减库存。
    4.commit tran原因是在查询库存之后,减库存之前,如果其他用户减库存,那么会造成程序无法自圆其说。查询还是必须在begin tran之后,尽管这样可能会加大事务处理的时间。应通过整体的、比较周全的策略来减小事务处理的时间,不能通过忽略数据准确性来提高效率。
      

  11.   

    to w_rose:
    在1.查询库存的时候就应该用排他锁锁住记录,使其他事务不能访问这条记录,然后做判断库存和扣减库存的操作,最后完成事务。这样可以防止其他事物在update前读取库存造成脏读,也防止其他事务对这条记录加锁,因为select操作通常加共享锁,如果两个事务同时对一条记录做发药操作可能会造成同时加共享锁,而不能更新库存,可能会引起死锁。