0

我正在处理这个项目,我们有一个保存实体的表单,在保存它之前,我们通过检查数据库上实体的唯一属性来检查记录是否不存在。

这工作得很好,除了在我们非常快速地多次按下提交表单按钮的情况下。在这种情况下,数据库检查不起作用,它会在数据库中创建多个记录条目。

我认为这是应用程序的设计问题,但我是工作单元模式的新手,我不明白为什么不工作。

这是我们在服务层做的检查:

    IEnumerable<Story> Stories = _unitOfWork.StoryRepository.Get(s => e.GUID.Equals(GUID));
    if (Stories.Count() > 0)
    {
        _unitOfWork. StoryRepository.Insert(newStory);
        _unitOfWork.Save();
    }

任何人都可以帮助解决这个问题吗?

顺便说一句,我不是基于 javascript 的解决方案,只是服务器端。

谢谢

编辑:该服务使用 ninject 并具有传递工作单元的构造函数:

    private IUnitOfWork _unitOfWork;

    public StoryService(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

我的 UnitOfWork 类被声明为:

public class UnitOfWork : Disposable, IUnitOfWork

数据库工厂.cs:

public class DatabaseFactory : Disposable, IDatabaseFactory
{
    private myContext _dataContext;
    private readonly object _door = new object();

    public myContext Get()
    {
        lock (_door)
        {
            return _dataContext ?? (_dataContext = new myContext());
        }
    }

    protected override void DisposeCore()
    {
        if (_dataContext != null)
            _dataContext.Dispose();
    }
}

每次我按照 Pluc 的建议调用我的服务方法时,我是否应该创建一个 UnitOfWork 实例?

4

1 回答 1

0

很有可能,您过早地创建了工作单元。您的工作单元应该是一个 IDisposable 实体,以便您可以在需要时使用它,然后立即摆脱它。对于这种情况,使用语句变得非常好:

using(var unitOfWork = new UnitOfWork())
{
    IEnumerable<Story> Stories = unitOfWork.StoryRepository.Get(s => e.GUID.Equals(GUID));
    if (Stories.Count() > 0)
    {
        unitOfWork.StoryRepository.Insert(newStory);
        unitOfWork.Save();
    }
}

如果你的 UnitOfWork 是很早就创建的,并且 StoryRepository 很早就在另一个场合使用,那么 Stories 已经加载。如果您根据页面加载速度单击提交两次,那么您自己就有一个很好的竞争条件,如果您来自请求 #1 的 UnitOfWork 在请求 #2 延迟加载他之前没有保存他的上下文,那么这两个请求都会有完全相同的故事列表和条件都将通过。

如果您根据需要创建 UnitOfWork,它甚至不会加载 Stories,因此,进行不良条件测试的唯一窗口是 .Get() 存储库方法和 unitOfWork.Save 之间的 0.001ms ()。

请始终记住,UnitOfWork 可以通过一次批处理所有查询来优化您的数据访问。它不是数据缓存工具。创建它,使用它,倾倒它。在单个 Web 请求中创建两次或更多次没有害处。

于 2012-10-31T12:01:13.790 回答