2

我刚刚阅读了这个 SO 问题,哪种设计最可取:test-create、try-create、create-catch?

关于答案,似乎开发人员更喜欢“Try-Create”模式,其中一些人提到TryCreate(user, out resultCode)可以是线程安全的,但其他模式不是。

尝试创建

enum CreateUserResultCode
{
    Success,
    UserAlreadyExists,
    UsernameAlreadyExists
}

if (!TryCreate(user, out resultCode))
{
    switch(resultCode)
    {
        case UserAlreadyExists: act on user exists error;
        case UsernameAlreadyExists: act on username exists error;
    }
}

我在想如果tryCreate方法涉及多个数据库调用,那么在实际实践中使其线程安全的正确方法是什么?

tryCreate会做两件事:

  1. 检查数据库中是否存在用户名

  2. 如果名称不存在,则创建一个新名称

很有可能一个线程完成了 1 而不是 2,另一个线程开始调用这个方法tryCreate并且也完成了 1,这是一个竞争条件。

当然,在tryCreate我可以添加一个锁或某事,但它会使tryCreate成为热点。如果我有一个高知名度的网站,所有新注册都必须等待tryCreate中的锁定。

我从其他网站看到的是当你输入你的用户名时,它会触发一个ajax调用来检查它是否存在于当前数据库中,然后你去下一步创建它。(不确定是否创建了一个锁此刻。)

关于如何在现实生活中实现涉及多个数据库调用的适当安全tryCreate的任何想法?

更新 1TryCreate的逻辑可能非常复杂,而不仅仅是 2 个 db 调用

4

1 回答 1

0

线程安全概念不会产生于数据库。因此,无论您在客户端做什么,对数据库端都没有影响,纯粹是因为数据库在设计上支持来自多个客户端的多个并发连接。

而是使用事务在数据库端执行几个操作作为原子操作。

于 2013-05-01T09:08:05.933 回答