【问题标题】:How to implement a thread-safe counter at database level?如何在数据库级别实现线程安全计数器?
【发布时间】:2020-09-27 17:12:41
【问题描述】:

我有一个名为“stats”的表,其中只有一行用于统计信息。我想在注册新产品时更新此表的“totalProductCount”列。(注册新产品时将totalProductCount增加一)

问题是我的应用程序的注册模块是多线程的,我认为当我从不同的线程调用此方法时会发生争用情况。有什么方法可以增加不同线程的列值?

public void increaseProductCount(long reqId) {
    EntityManager em = emf.createEntityManager();
    EntityTransaction transaction = em.getTransaction();
    transaction.begin();

    Query query = em.createNativeQuery("update stats set total_product_count = total_product_count + 1 where id = 1");
    query.executeUpdate();

    transaction.commit();
}

【问题讨论】:

  • 这段代码和多线程有什么问题?在 10 个并发线程之后,该值将相同,因为数据库将(取决于您的设置)让它们等待直到先前的更新被提交。您的产品注册是否也是该数据库的一部分?如果不是,并且您正在寻找的只是一个数据库计数器,您可能需要查看序列对象。

标签: java database multithreading jpa


【解决方案1】:

您是否真的遇到过竞争条件的实例?

所有UPDATE 语句都是原子的,并获取更新数据的写锁。只要您至少使用READ COMMITED 隔离级别(无论如何都建议您不要这样做),您应该没问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    相关资源
    最近更新 更多