在数据库上解决竞争条件的最佳方法



我有一个为电影保存字幕的应用程序。我需要防止出现两个字幕重叠的情况。首先,我将定义什么是重叠字幕。假设caption类有MovieId、EntryTime、ExistTime和Text。EntryTime是一个数字,表示字幕在电影中显示的时间(以毫秒为单位(,ExistTime是字幕将在电影中消失的时间。如果我们有两个标题如下

var caption1 = new Caption(){MovieId = 1, EntryTime = 100, ExistTime =200}
var caption2 = new Caption(){MovieId = 1, EntryTime = 120, ExistTime =220}

它们是重叠的,但以下标题不是

var caption3 = new Caption(){MovieId = 1, EntryTime = 400, ExistTime =450}
var caption4 = new Caption(){MovieId = 2, EntryTime = 425, ExistTime =470}

所有电影的所有字幕都保存在同一数据库中,数据库中的表相同。

为了避免插入重叠的标题,我首先尝试在服务器代码中加一个锁。此代码专门检查标题的EntryTime和EndTime,不检查重叠场景,但此检查应支持重叠情况

lock (insertCaptionLocker)
{
var captionExists = dbCaptions.Captions.Any(x =>
x.MovieId == caption.MovieId && x.EntryTime == caption.EntryTime &&
x.ExitTime == caption.ExitTime);
if (!captionExists)
{
dbCaptions.Captions.InsertOnSubmit(caption);
}
dbCaptions.SubmitChanges();
}

我对这个代码有一些问题:

  1. 它并不总是一个关键部分——大多数时候,它应该可以允许一个以上的线程输入此代码。只有当我们有两个(或更多(线程试图以重叠的时间更新同一个MovieId时,我们才会遇到问题
  2. 如果我们有一个以上的服务器与负载均衡器连接,这将不起作用

我认为解决方案应该以某种方式来自数据库,但我不知道该使用什么。任何帮助都将不胜感激。

观察:

您的条件仅在给定MovieId已经存在具有相同EntryTime和ExistTime的字幕时进行检查,而不检查它们是否重叠。

对于非重叠,您应该检查类似的内容,检查开始和每对的完成时间:

var non_overlapping = dbCaptions.Captions.Any(x =>
x.MovieId == caption.MovieId &&( x.EntryTime < caption.EntryTime && x.ExitTime < caption.EntryTime || x.EntryTime > caption.EntryTime && caption.ExitTime < x.EntryTime )

这些对将不重叠,因此您可以插入它们。使用您的方法,您只会得到完全相同的标题,但不是所有重叠的标题,ypu还可以定义一个范围,并检查元组(x.EntryTime ,x.ExitTime)是否在range(caption.EntryTime ,caption.ExitTime)中。

相关内容

  • 没有找到相关文章

最新更新