【发布时间】:2017-04-29 16:41:24
【问题描述】:
例如,我们有一个表(登录名、哈希表)。我们对登录列没有unique 约束,但我们应该保持它的唯一性(仅作为示例)。
当新用户注册时,我们会检查输入的登录是否免费。
如果它是部署到 Tomcat 的具有线程池的 Java Web 应用程序,那么这些检查可能会并行处理,对吗?那么如何保证唯一性呢?
【问题讨论】:
标签: java multithreading web-applications
例如,我们有一个表(登录名、哈希表)。我们对登录列没有unique 约束,但我们应该保持它的唯一性(仅作为示例)。
当新用户注册时,我们会检查输入的登录是否免费。
如果它是部署到 Tomcat 的具有线程池的 Java Web 应用程序,那么这些检查可能会并行处理,对吗?那么如何保证唯一性呢?
【问题讨论】:
标签: java multithreading web-applications
简而言之,这里没有数据库的限制,你不可能有一个好的解决方案。
如果在多线程环境中没有限制,您将需要一些公共资源来同步您的线程。一个线程将获取互斥锁,检查登录是否空闲(使用SELECT),然后INSERT 一个新记录是否空闲。没有其他线程应该能够同时执行此操作 - 这就是您需要在此处进行同步的原因。
如果您的所有线程都可以访问此互斥体并且保证没有其他人可以同时访问数据库,这将起作用。
如果您有几台机器访问同一个数据库,则会出现第一个问题。在不同机器上运行的线程将无法访问相同的互斥锁,因此它们会很高兴地并行插入您的表中。
另一个问题是,如果有人登录数据库并直接在该表中创建记录,则此类插入可能恰好发生在从您的代码执行的 SELECT 和 INSERT 之间。所以代码中的同步在这里无济于事。
另一种选择是锁定整个表,但情况更糟。您需要非常可靠地释放锁,否则您将面临整个系统停滞的风险。
【讨论】:
您可以在表中使用悲观锁,这将锁定表,您可以检查是否有并保存,因此其他线程暂时无法更改该表。但我认为这是一种非常糟糕的做事方式,为什么不使用数据库约束呢?
【讨论】: