鉴于您有一天可能希望扩展到多个应用服务器,内存同步实现也可能不足以保证电子邮件不重复。
最简单的解决方法之一是在数据库级别实现批处理机制。
在一个工作单元下
- 读取 N x 记录,使用悲观锁定(即防止其他线程同时读取相同的电子邮件)
- 用批次 ID(或
IsProcessed
指标)标记这些记录
- 将记录返回到您的应用程序
例如,SQL 服务器中的批处理 PROC 可能看起来像(假设 table = dbo.Emails,它有一个 PK EmailId 和一个已处理的指示符 BIT 字段IsProcessed
):
CREATE PROC dbo.GetNextBatchOfEmails
AS
BEGIN
-- Identify the next N emails to be batched. UPDLOCK is to prevent another thread batching same emails
SELECT top 100 EmailId
INTO #tmpBatch
FROM dbo.Emails WITH (UPDLOCK)
WHERE IsProcessed = 0
-- Stamp emails as sent. Assumed that PROC is called under a UOW. The batch IS the UOW
UPDATE e
SET e.IsProcessed = 1
FROM dbo.Emails e
INNER JOIN #tmpBatch t
on e.EmailId = t.EmailId
-- Return the batch of emails to caller
SELECT e.*
FROM dbo.Emails e
INNER JOIN #tmpBatch t
on e.EmailId = t.EmailId
END
Then expose the PROC as an EF Function Import mapped to your Email Entity. Under a TransactionScope
ts, you can then call the EF Function Import, and send emails, and call ts.Complete() on success.