我有一个使用T/SQL过程更新的表DB.DATA_FEED
。对于不同的数据,每分钟执行下面的过程100次。UPDATE和SELECT之间的冲突
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>[email protected] 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代码有问题吗?我能做些什么来防止将来发生这种锁?
感谢
您是否考虑过使用读取已提交的快照来运行您的SELECT? – 2013-04-25 13:02:05
我不知道这件事......你是在暗示我'ALTER DATABASE DB SET READ_COMMITTED_SNAPSHOT ON'或者是按查询查询的级别。 – gordon613 2013-04-25 13:25:56
那么它必须在数据库级别启用,然后明确设置特定的查询(数据库级别设置才有可能)。当然,你应该对你的总体工作量进行测试,我并不是说只是把它打开。如果脏读是可以接受的(通过选择运行的频率,这是很有可能的),你也可以考虑读取未提交。 – 2013-04-25 13:35:17