【发布时间】:2016-02-15 11:39:57
【问题描述】:
我有一种情况,每条新记录都应该包含一个唯一且可读的值。 该值对用户具有业务意义,将在我们的数据库中作为自然 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'
...
这个商业价值是由工厂创造的:
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;
}
}
Service 层将调用工厂并保存新的 Invoice:
@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 表。我认为在将新的 Invoice 实体保存到 DB 之前,此锁应该处于活动状态。
我应该如何在 Hibernate 中执行此操作?
【问题讨论】:
-
一个序列可以帮助你。你可以创建一个吗?
-
我不知道如何创建序列。你能给我更多关于这方面的信息吗?序列是否会阻止 2 个并发事务使用相同的值?
标签: java hibernate jpa transactions locking