比较 Exchange 同步多个保留唯一约束

问题描述

当我阅读 Compare Exhange for RavenDB 时,我在用于保留电子邮件的文档中发现了以下用户案例。基本上是一种强制执行 UNIQUE 约束的方法。如果您只想对一个属性强制执行此约束,但如果您引入多个属性(电子邮件和用户名),它不再按预期工作,则此方法非常有效。

在文档中查看:Link

class Program
{
    public class User
    {
        public string Id { get; set; }

        public string Name { get; set; }

        public string Email { get; set; }
    }

    static void Main(string[] args)
    {
        var store = new DocumentStore()
        {
            Urls = new[] {
                "http://127.0.0.1:8080/"
            },Database = "example",}.Initialize();

        string name = "admin";
        string email = "[email protected]";

        var user = new User
        {
            Name = name,Email = email
        };

        using (IDocumentSession session = store.OpenSession())
        {
            session.Store(user);

            // Try to reserve a new user email 
            // Note: This operation takes place outside of the session transaction,//       It is a cluster-wide reservation
            CompareExchangeResult<string> namePutResult
                = store.Operations.Send(
                    new PutCompareExchangeValueOperation<string>("names/" + name,user.Id,0));


            if (namePutResult.Successful == false)
            {
                throw new Exception("Name is already in use");
            }
            else
            {
                // Try to reserve a new user email 
                // Note: This operation takes place outside of the session transaction,//       It is a cluster-wide reservation
                CompareExchangeResult<string> emailPutResult
                    = store.Operations.Send(
                        new PutCompareExchangeValueOperation<string>("emails/" + email,0));

                // Unlock name again (Because if we dont the name wil be locked)
                if (emailPutResult.Successful == false)
                {
                    // First,get existing value
                    CompareExchangeValue<string> readResult =
                        store.Operations.Send(
                            new GetCompareExchangeValueOperation<string>("names/" + name));

                    // Delete the key - use the index received from the 'Get' operation
                    CompareExchangeResult<string> deleteResult
                        = store.Operations.Send(
                            new DeleteCompareExchangeValueOperation<string>("names/" + name,readResult.Index));

                    // The delete result is successful only if the index has not changed between the read and delete operations
                    if (deleteResult.Successful == false)
                    {
                        throw new Exception("The name is forever lost");
                    }
                    else
                    {
                        throw new Exception("Email is already in use");
                    }
                }
            }

            // At this point we managed to reserve/save both the user name and email
            // The document can be saved in SaveChanges
            session.SaveChanges();
        }
    }
}

在上面的示例中,您可以看到为什么这不再按预期工作。因为现在,如果电子邮件比较交换失败或已经被采用,则名称比较交换无法撤消/删除,因为删除比较交换理论上可能会失败。现在因为这个有一个更改,用户名将被永久锁定,不能再次使用。当您尝试更新用户名时也会发生同样的问题,因为一旦保留了新用户名,您就必须解锁/删除旧用户名的比较交换。

解决此类问题的最佳方法是什么?这种情况发生了哪些变化?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)