install.sql 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. IF OBJECT_ID(N'dbo.XiaoshuSyncCommandLog', N'U') IS NULL
  2. BEGIN
  3. CREATE TABLE dbo.XiaoshuSyncCommandLog (
  4. Id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
  5. IdempotencyKey nvarchar(128) NOT NULL,
  6. Operation nvarchar(100) NOT NULL,
  7. Actor nvarchar(200) NOT NULL,
  8. Reason nvarchar(500) NOT NULL,
  9. PayloadJson nvarchar(max) NOT NULL,
  10. ResultJson nvarchar(max) NULL,
  11. State varchar(20) NOT NULL,
  12. CreatedAt datetime2(3) NOT NULL CONSTRAINT DF_XiaoshuSyncCommandLog_CreatedAt DEFAULT SYSUTCDATETIME(),
  13. CompletedAt datetime2(3) NULL,
  14. CONSTRAINT UQ_XiaoshuSyncCommandLog_Idempotency UNIQUE (IdempotencyKey)
  15. );
  16. END;
  17. GO
  18. CREATE OR ALTER PROCEDURE dbo.XiaoshuSync_ExecuteCommand
  19. @Operation nvarchar(100), @Actor nvarchar(200), @Reason nvarchar(500),
  20. @IdempotencyKey nvarchar(128), @ExpectedUpdatedAt nvarchar(50) = NULL,
  21. @PayloadJson nvarchar(max), @ResultJson nvarchar(max) OUTPUT
  22. AS
  23. BEGIN
  24. SET NOCOUNT ON; SET XACT_ABORT ON;
  25. IF ISJSON(@PayloadJson) <> 1 THROW 51000, N'写入负载必须是有效 JSON', 1;
  26. BEGIN TRANSACTION;
  27. EXEC sys.sp_getapplock @Resource=N'xiaoshu-sync-command:'+@IdempotencyKey,@LockMode='Exclusive',@LockOwner='Transaction',@LockTimeout=10000;
  28. SELECT @ResultJson=ResultJson FROM dbo.XiaoshuSyncCommandLog WHERE IdempotencyKey=@IdempotencyKey AND State='completed';
  29. IF @ResultJson IS NOT NULL BEGIN COMMIT; RETURN; END;
  30. IF NOT EXISTS (SELECT 1 FROM dbo.XiaoshuSyncCommandLog WHERE IdempotencyKey=@IdempotencyKey)
  31. INSERT dbo.XiaoshuSyncCommandLog(IdempotencyKey,Operation,Actor,Reason,PayloadJson,State) VALUES(@IdempotencyKey,@Operation,@Actor,@Reason,@PayloadJson,'processing');
  32. /* 在此调用旧站 BLL/正式存储过程,与本日志同一事务并回写 ResultJson。 */
  33. ROLLBACK;
  34. THROW 51001, N'该写入操作尚未与旧站业务逻辑绑定,已安全拒绝', 1;
  35. END;
  36. GO