日期:2014-05-17  浏览次数:20682 次

ROWLOCK 失效,两个请求同时进行事务 重复写入数据 求救
说明:
  UPDATE Deposits WITH (ROWLOCK) SET status=4,UpdateTime=getdate() WHERE DepositId=@billno;

  DepositId请求过来,会存在两次提交的可能,所以,我做了行锁定处理,一直运行良好,没有问题

  近一个月,频繁出现了3次重复写入的问题。

  更新时锁定行,但出现同一DepositId 两次操作,写入重复数据

  怀疑是两个请求条数据 同时进入事务,行锁没有起做用
   
  那位大侠有空,帮忙指点一下,感激不尽。。。。

SQL code
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go






--功能:online_Deposit加款 


ALTER proc [dbo].[P_Online_Deposit_Process]
 @billno varchar(50),  --存款编号
 @UpdateBy varchar(50),
 @UpdateIp varchar(64),
 @amount money,
 @Remark varchar(50),
 @TypeID int
as
  declare @beforeBalance money;
  declare @afterBalance money;
  declare @TrueDeposited money;
  declare @UserId uniqueidentifier ;
  declare @status int;

--lv等级判断参数
  declare @depositnum   int;
  declare @totaldeposit int;
  declare @levelid  int; 
  declare @beforeLevelid  int; 
BEGIN
    
    SET NOCOUNT ON;
     set xact_abort on;
 
        If not exists(SELECT  TrueDeposited,DepositId FROM Deposits WHERE  DepositId=@billno and TrueDeposited=@amount) 
          begin
           select '1' flag,N'交易失败:不存在此订单或交易金额与数据库中不相同.' msg
           RETURN;
        end 



    SELECT @UserId=UserId,@status=status  FROM Deposits  WHERE DepositId=@billno;
   if(@status=4 or @status=5) begin
        select '1' flag,N'交易失败:该记录已经处理完成,不允许在次操作.' msg
        return;
    end;

 if(@TypeID=1) begin

     if(@status=1) begin
      
      Begin Tran ;--充值 事务处理开始
 
              --更新存款记录状态
       UPDATE Deposits  WITH (ROWLOCK)  SET status=4,UpdateTime=getdate()   WHERE DepositId=@billno;
    
     select @beforeBalance=Balance FROM Users WHERE UserId=@UserId;--之前主帐户余额 

        --写入存款记录状态更新日志
    insert into log_UsersDeposit (Id,Remark,TranID,status,UserId,UpdateBy,UpdateIp,UpdateTime) values (newid

(),@Remark,@billno,'Success',@UserId,'IPS',@UpdateIp,getdate());
        --对主帐号进行实际充值
        UPDATE Users SET Balance=Balance+@amount,totaldeposit=totaldeposit+@amount,depositnum=depositnum+1,UpdateTime=getdate(),Updateby=@UpdateBy  WHERE 

UserId=@UserId;  
        select @afterBalance=Balance FROM Users WHERE UserId=@UserId;--充值之后主帐户余额     
        
        select @totaldeposit=(SELECT totaldeposit FROM Users WHERE UserId=@UserId);--totaldeposit 
        select @depositnum=(SELECT depositnum FROM Users WHERE UserId=@UserId);--depositnum 
        select @beforeLevelid=(SELECT UserLevel FROM Users WHERE UserId=@UserId);--beforeLevelid
        select @levelid=(SELECT top 1 levelid FROM T_LevelMap  where depositnum<=@depositnum and totaldeposit<=@totaldeposit  order by levelid desc);--UserLevel 
        UPDATE Users SET UserLevel=@levelid WHERE UserId=@UserId  and @levelid>@beforeLevelid;   
        -----------------写入主帐户变动日志开始----------
        insert into log_UsersBlance  (Id,Remark,TranID,tranType,Operating,Amt,beforeBalance,afterBalance,UserId,UpdateBy,UpdateIp,UpdateTime) values 
          (newid(),@Remark,@billno,1,'+',@amount,@beforeBalance,@afterBalance,@UserId,@UpdateBy,@UpdateIp,getdate());
        
               if (@@error <> 0) begin
                select '1' flag,N'交易失败:该记录已经处理完成.' msg
                rollback tran ;
                return;
             end

        Commit Tran;  --事务处理结束       
       
       select '0' flag,N'交易成功: Sussce.' msg 
     end
  end
 else if(@TypeID=5) begin
    Begin Tran ;
      UPDATE Deposits WITH (ROWLOCK)  SET  status=5,UpdateTime=getdate(),Updateby=@Updateby  where  DepositId=@billno;
        --写入存款记录状态更新日志
      insert into log_UsersDeposit  (Id,Remark,TranID,status,UserId,UpdateBy,UpdateIp,UpdateTime) values  
     (newid(),@Remark,@billno,'Reject',@UserId,@Updateby,@UpdateIp,getdate()) ;

        
               if (@@error <> 0) begin
                select '1' flag,N'交易失败:已经