select 涉及全文搜索的已提交插入数据无法立即使用
committed inserted data not immediately available for select involving full text search
我有 2 个存储过程 - simplified/pseudo 代码:
CREATE PROCEDURE [SomeSchema].[Sproc1]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION X;
-- Insert lots of data
COMMIT TRANSACTION X;
END TRY
BEGIN CATCH
SELECT
@ErrorNumber = ERROR_NUMBER() ,
@ErrorSeverity = ERROR_SEVERITY() ,
@ErrorState = ERROR_STATE() ,
@ErrorProcedure = ERROR_PROCEDURE() ,
@ErrorLine = ERROR_LINE() ,
@ErrorMessage = ERROR_MESSAGE();
ROLLBACK TRANSACTION X;
END CATCH;
END;
CREATE PROCEDURE [SomeSchema].[Sproc2]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION X;
-- Perform full text search on old and inserted data and return
COMMIT TRANSACTION X;
END TRY
BEGIN CATCH
SELECT
@ErrorNumber = ERROR_NUMBER() ,
@ErrorSeverity = ERROR_SEVERITY() ,
@ErrorState = ERROR_STATE() ,
@ErrorProcedure = ERROR_PROCEDURE() ,
@ErrorLine = ERROR_LINE() ,
@ErrorMessage = ERROR_MESSAGE();
ROLLBACK TRANSACTION X;
END CATCH;
END;
第一个存储过程 Sproc1 将一些数据插入到几个规范化表中。第二个 Sproc2 然后使用全文搜索从数据库中选择数据。我运行两个存储过程如下:
EXEC [SomeSchema].[Sproc1]
EXEC [SomeSchema].[Sproc2]
不幸的是,当 Sproc2 为 运行 时,通过 Sproc1 插入的数据尚不可用 - 仅在大约 1-3 秒后(猜测)。这可能是什么原因?所有这些不应该是 synchronous/atomic - 即在 Sproc2 执行时数据应该是 available/selectable 吗?
任何强制执行数据 insert/index 在调用 Sproc2 之前完成的建议将不胜感激。谢谢。
PS:
刚刚将问题隔离在 Sproc2 内部调用的存储过程中。此存储过程在事务中使用 sp_executesql 而不是 运行。不知道为什么这会导致问题...
PPS:
这一切似乎都与全文搜索有关。这是我的 SSDT post-部署脚本的一部分:
CREATE FULLTEXT CATALOG [SomeFullTextCatalog]
WITH ACCENT_SENSITIVITY = OFF
AS DEFAULT;
CREATE UNIQUE CLUSTERED INDEX ClusteredIndex_SomeView
ON [SomeSchema].[SomeView] (SomeId);
GO
CREATE FULLTEXT INDEX ON [SomeSchema].[SomeView ](
[Some1] LANGUAGE 'British English',
[Some2] LANGUAGE 'British English',
[Some3] LANGUAGE 'British English',
[Some4] LANGUAGE 'British English')
KEY INDEX [ClusteredIndex_SomeView] ON ([SomeFullTextCatalog], FILEGROUP [PRIMARY])
WITH (CHANGE_TRACKING = AUTO, STOPLIST = SYSTEM)
插入后如何'refresh'这个?
我能做到:
我明白我能做到:
SELECT FULLTEXTCATALOGPROPERTY('SomeFullTextCatalog', 'PopulateStatus') AS Status
查看全文目录的状态,等待其值再次为0。这可能吗?
是否需要重新创建全文索引,实际上需要每天重新创建一次,以获取当天所有插入的数据。
问题是全文索引需要一些时间来刷新。为了创建等待,我使用了从 here:
中获取的存储过程
CREATE PROCEDURE [Core].[USP_Core_WaitForFullTextIndexing]
@CatalogName VARCHAR(MAX)
AS
BEGIN
DECLARE @status int;
SET @status = 1;
DECLARE @waitLoops int;
SET @waitLoops = 0;
WHILE @status > 0 AND @waitLoops < 100
BEGIN
SELECT @status = FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
FROM sys.fulltext_catalogs AS cat;
IF @status > 0
BEGIN
-- prevent thrashing
WAITFOR DELAY '00:00:00.1';
END
SET @waitLoops = @waitLoops + 1;
END
END
我有 2 个存储过程 - simplified/pseudo 代码:
CREATE PROCEDURE [SomeSchema].[Sproc1]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION X;
-- Insert lots of data
COMMIT TRANSACTION X;
END TRY
BEGIN CATCH
SELECT
@ErrorNumber = ERROR_NUMBER() ,
@ErrorSeverity = ERROR_SEVERITY() ,
@ErrorState = ERROR_STATE() ,
@ErrorProcedure = ERROR_PROCEDURE() ,
@ErrorLine = ERROR_LINE() ,
@ErrorMessage = ERROR_MESSAGE();
ROLLBACK TRANSACTION X;
END CATCH;
END;
CREATE PROCEDURE [SomeSchema].[Sproc2]
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION X;
-- Perform full text search on old and inserted data and return
COMMIT TRANSACTION X;
END TRY
BEGIN CATCH
SELECT
@ErrorNumber = ERROR_NUMBER() ,
@ErrorSeverity = ERROR_SEVERITY() ,
@ErrorState = ERROR_STATE() ,
@ErrorProcedure = ERROR_PROCEDURE() ,
@ErrorLine = ERROR_LINE() ,
@ErrorMessage = ERROR_MESSAGE();
ROLLBACK TRANSACTION X;
END CATCH;
END;
第一个存储过程 Sproc1 将一些数据插入到几个规范化表中。第二个 Sproc2 然后使用全文搜索从数据库中选择数据。我运行两个存储过程如下:
EXEC [SomeSchema].[Sproc1]
EXEC [SomeSchema].[Sproc2]
不幸的是,当 Sproc2 为 运行 时,通过 Sproc1 插入的数据尚不可用 - 仅在大约 1-3 秒后(猜测)。这可能是什么原因?所有这些不应该是 synchronous/atomic - 即在 Sproc2 执行时数据应该是 available/selectable 吗?
任何强制执行数据 insert/index 在调用 Sproc2 之前完成的建议将不胜感激。谢谢。
PS:
刚刚将问题隔离在 Sproc2 内部调用的存储过程中。此存储过程在事务中使用 sp_executesql 而不是 运行。不知道为什么这会导致问题...
PPS:
这一切似乎都与全文搜索有关。这是我的 SSDT post-部署脚本的一部分:
CREATE FULLTEXT CATALOG [SomeFullTextCatalog]
WITH ACCENT_SENSITIVITY = OFF
AS DEFAULT;
CREATE UNIQUE CLUSTERED INDEX ClusteredIndex_SomeView
ON [SomeSchema].[SomeView] (SomeId);
GO
CREATE FULLTEXT INDEX ON [SomeSchema].[SomeView ](
[Some1] LANGUAGE 'British English',
[Some2] LANGUAGE 'British English',
[Some3] LANGUAGE 'British English',
[Some4] LANGUAGE 'British English')
KEY INDEX [ClusteredIndex_SomeView] ON ([SomeFullTextCatalog], FILEGROUP [PRIMARY])
WITH (CHANGE_TRACKING = AUTO, STOPLIST = SYSTEM)
插入后如何'refresh'这个?
我能做到:
我明白我能做到:
SELECT FULLTEXTCATALOGPROPERTY('SomeFullTextCatalog', 'PopulateStatus') AS Status
查看全文目录的状态,等待其值再次为0。这可能吗?
是否需要重新创建全文索引,实际上需要每天重新创建一次,以获取当天所有插入的数据。
问题是全文索引需要一些时间来刷新。为了创建等待,我使用了从 here:
中获取的存储过程CREATE PROCEDURE [Core].[USP_Core_WaitForFullTextIndexing]
@CatalogName VARCHAR(MAX)
AS
BEGIN
DECLARE @status int;
SET @status = 1;
DECLARE @waitLoops int;
SET @waitLoops = 0;
WHILE @status > 0 AND @waitLoops < 100
BEGIN
SELECT @status = FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
FROM sys.fulltext_catalogs AS cat;
IF @status > 0
BEGIN
-- prevent thrashing
WAITFOR DELAY '00:00:00.1';
END
SET @waitLoops = @waitLoops + 1;
END
END