说明:
UPDATE Deposits WITH (ROWLOCK) SET status=4,UpdateTime=getdate() WHERE [email protected];
DepositId请求过来,会存在两次提交的可能,所以,我做了行锁定处理,一直运行良好,没有问题
近一个月,频繁出现了3次重复写入的问题。
更新时锁定行,但出现同一DepositId 两次操作,写入重复数据
怀疑是两个请求条数据 同时进入事务,行锁没有起做用
那位大侠有空,帮忙指点一下,感激不尽。。。。
- SQL code
set ANSI_NULLS ONset QUOTED_IDENTIFIER ONgo--功能:online_Deposit加款 ALTER proc [dbo].[P_Online_Deposit_Process] @billno varchar(50), --存款编号 @UpdateBy varchar(50), @UpdateIp varchar(64), @amount money, @Remark varchar(50), @TypeID intas 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 [email protected] and [email protected]) begin select '1' flag,N'交易失败:不存在此订单或交易金额与数据库中不相同.' msg RETURN; end SELECT @UserId=UserId,@status=status FROM Deposits WHERE [email protected]; 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 [email protected]; select @beforeBalance=Balance FROM Users WHERE [email protected];--之前主帐户余额 --写入存款记录状态更新日志 insert into log_UsersDeposit (Id,Remark,TranID,status,UserId,UpdateBy,UpdateIp,UpdateTime) values (newid(),@Remark,@billno,'Success',@UserId,'IPS',@UpdateIp,getdate()); --对主帐号进行实际充值 UPDATE Users SET [email protected],[email protected],depositnum=depositnum+1,UpdateTime=getdate(),[email protected] WHERE [email protected]; select @afterBalance=Balance FROM Users WHERE [email protected];--充值之后主帐户余额 select @totaldeposit=(SELECT totaldeposit FROM Users WHERE [email protected]);--totaldeposit select @depositnum=(SELECT depositnum FROM Users WHERE [email protected]);--depositnum select @beforeLevelid=(SELECT UserLevel FROM Users WHERE [email protected]);--beforeLevelid select @levelid=(SELECT top 1 levelid FROM T_LevelMap where depositnum<[email protected] and totaldeposit<[email protected] order by levelid desc);--UserLevel UPDATE Users SET [email protected] WHERE [email protected] 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(),[email protected] where [email protected]; --写入存款记录状态更新日志 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'交易失败:已经处理完成' msg rollback tran ; return; end Commit Tran; select '0' flag,N'交易失败: Reject.' msg endEND