gpt4 book ai didi

java - 如何在读写操作之间锁定表

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:09:13 24 4
gpt4 key购买 nike

我的情况是每条新记录都应该包含一个唯一且可读的值。该值对用户具有业务意义,将在我们的数据库中作为自然 ID(在主键旁边)处理。

让您了解值的结构:

 - record 1 has business value 'INVOICE_AAA_001'
- record 2 has business value 'INVOICE_AAA_002'
...
- record 999 has business value 'INVOICE_AAA_999'
- record 1000 has business value 'INVOICE_BAA_001'
- record 1001 has business value 'INVOICE_BAA_002'
...

这个商业值(value)是由工厂创造的:

class BusinessFactory {

...

public String createUniqueValue() {
String lastValue = (String) getSession().createQuery("select businessValue " +
"from Invoice as invoice " +
"order by businessValue")
.setMaxResults(1)
.setReadOnly(true)
.uniqueResult();

// generate new value

return newValue;
}

}

服务层将调用工厂并保存一个新的发票:

  @Transactional
public void saveNewInvoice() {
final String newValue = businessFactory.createUniqueValue();
Invoice invoice = new Invoice(newValue);
invoiceRepository.save(invoice);
}

这里的问题是,可能存在 trx1 和 trx2 读取业务值“INVOICE_BAA_002”的情况。接下来发生的是 2 个 trx 使用相同的值。第一个提交的 trx 将成功,第二个将由于唯一约束异常而失败。

因此,在读取最新的业务值时,我需要锁定发票表。我认为在将新的 Invoice 实体保存到 DB 之前,此锁应该处于 Activity 状态。

我应该如何在 Hibernate 中执行此操作?

最佳答案

不是使用冲突检测并发控制机制,而是依赖唯一约束或 optimistic locking ,您可以使用悲观锁定。

你需要:

  1. 一个 InvoiceSequence 表,其中有一个实体映射到它

  2. 这张表只有一行,存放的是最新的invoice sequence值

  3. acquire an exclusive lock记录在案:

    InvoiceSequence invoiceSequence = em.find(InvoiceSequence.class, 1L, LockModeType.PESSIMISTIC_WRITE)
  4. 您使用业务逻辑递增序列并修改实体以存储最新值:

    String currentSequence = invoiceSequence.getValue();
    String nextSequence = sequenceGenerator.nextValue(currentSequence);
    invoiceSequence.setValue(nextSequence);

独占锁也会阻止并发读写。

关于java - 如何在读写操作之间锁定表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33700390/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com