具有多个db调用的方法的线程安全性



我刚刚读到这个问题:测试-创建、尝试-创建、创建-捕获,哪种设计更可取?

关于答案,似乎开发者更喜欢"Try-Create"模式,他们中的一些人提到TryCreate(user, out resultCode)可以是threadsafe,但其他模式不是。

Try-Create

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方法涉及多个db调用,在实际实践中使其线程安全的正确方法是什么?

tryCreate将做两件事:

  1. 检查db中是否存在用户名

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

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

当然,在tryCreate我可以添加一个锁或其他,但它会使tryCreate一个热点。如果我有一个高知名度的网站,所有新的寄存器必须等待锁定tryCreate

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

关于如何实现一个适当的安全的tryCreate在现实生活中涉及多个db调用的想法吗?

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

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

使用transactions在数据库端作为原子操作执行几个动作。

最新更新