【发布时间】:2010-09-12 17:26:33
【问题描述】:
在审批工作流程中,我想确保提醒电子邮件只发送一次。
使用 SqlCommand.ExecuteNonQuery 我可以通过测试返回值来确保这一点。 使用 EF 的推荐解决方案是什么? 根据文档 ObjectContext.SaveChanges 不返回等效值。
SqlCommand 示例: (TransactionScope 用于在 SendMail 失败时回滚数据库更新。)
Dim sql = "UPDATE LeaveApprovalRequests SET State = 'Reminded'" &
" WHERE ID=3 AND State <>'Reminded'"
Using scope As New TransactionScope
Using cnx As New SqlConnection(My.Settings.connectionString)
cnx.Open()
Dim cmd As New SqlCommand(sql, cnx)
If 1 = cmd.ExecuteNonQuery Then
SendMail()
End If
scope.Complete()
End Using
End Using
通过启用乐观并发(在 RowVersion 属性上使用 ConcurrencyMode=Fixed)并捕获 OptimisticConcurrencyException,我能够确定对象是否在存储中实际更新。 现在 TransactionScope(用于在 SendMail 失败时回滚数据库更新)引发死锁错误。 为什么?
Using scope As New TransactionScope
Using ctx As New ApprovalEntities
Try
Dim approval = ctx.LeaveApprovalRequests.
Where(Function(r) r.ID = 3 And r.State = "Created"
).FirstOrDefault
If approval Is Nothing Then
Console.WriteLine("not found")
Exit Sub
End If
Threading.Thread.Sleep(4000)
approval.State = "Reminded"
ctx.SaveChanges()
SendMail()
Catch ex As OptimisticConcurrencyException
Exit Try
End Try
End Using
scope.Complete()
End Using
【问题讨论】: