UPDATE和SELECT之间的冲突

时间:2013-04-25 11:18:21

标签: tsql sql-server-2012

我有一个表DB.DATA_FEED,我使用T / SQL过程更新。每分钟,对于不同的数据,下面的过程执行100次。

ALTER PROCEDURE [DB].[UPDATE_DATA_FEED]  
   @P_MARKET_DATE varchar(max),
   @P_CURR1 int,
   @P_CURR2 int,
   @P_PERIOD float(53),
   @P_MID float(53)
AS 

   BEGIN

      BEGIN TRY

         UPDATE DB.DATA_FEED
            SET 
               MID = @P_MID, 
               MARKET_DATE = convert(datetime,@P_MARKET_DATE, 103)
            WHERE 
               cast(MARKET_DATE as date) = 
               cast(convert(datetime,@P_MARKET_DATE, 103) as date) AND 
            CURR1 = @P_CURR1 AND 
            CURR2 = @P_CURR2 AND 
            PERIOD = @P_PERIOD

         IF @@TRANCOUNT > 0
            COMMIT WORK 

      END TRY

      BEGIN CATCH

         --error code

      END CATCH

   END

 END

当用户使用该应用程序时,他们也会从该表中读取,如下面的SQL所示。这种选择可能会在一分钟内运行数千次。 (问题标记由具有适当日期/数字的解析器替换)

DECLARE @MYDATE AS DATE;
SET @MYDATE='?'
SELECT *
FROM DB.DATA_FEED
WHERE MARKET_DATE>=@MYDATE AND MARKET_DATE<DATEADD(D,1,@MYDATE)
AND CURR1 = ?
AND CURR2 = ?
AND PERIOD = ?

ORDER BY PERIOD

我有时虽然很少有数据库锁。

使用http://sqlserverplanet.com/troubleshooting/blocking-processes-lead-blocker中的脚本,我看到它是SPID = 58。然后我做了DECLARE @SPID INT; SET @SPID = 58; DBCC INPUTBUFFER(@SPID)找到原来是我的select语句的SQL脚本。

我的SQL代码有问题吗?我可以做些什么来防止将来发生此类锁定?

由于

1 个答案:

答案 0 :(得分:0)

读者优先于作家,所以当有人写作时,读者必须等待写作完成。有两个Table Hints你可以尝试一个是NOLOCK读取未通信的行(脏读),另一个是READPAST(只读取上次提交时提交的信息)。在这两种情况下,读者永远不会阻止表格,因为不会使作家陷入僵局。

编写者可以阻止其他编写者,但是,如果我理解正确,每次执行只能写一次,这样读者就会插入写入,从而减少死锁。

希望它有所帮助。