我有这样一种情况,即每条新记录都应该包含一个唯一的、可读的值。此值对用户具有业务意义,并将作为数据库中的自然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;
}
}服务层将调用工厂并保存新发票:
@Transactional
public void saveNewInvoice() {
final String newValue = businessFactory.createUniqueValue();
Invoice invoice = new Invoice(newValue);
invoiceRepository.save(invoice);
}这里的问题是,可能存在这样一种情况,即trx1和trx2读取业务值‘发票_BAA_002’。接下来发生的情况是,2个trx的值是相同的。第一次提交的trx将成功,第二次由于唯一的约束异常而失败。
因此,在读取最新的业务价值时,我需要在发票表上设置一个锁。我认为这个锁应该是活动的,直到新的发票实体被保存到DB。
我应该如何在Hibernate中做到这一点?
发布于 2015-11-15 15:15:59
不使用冲突检测并发控制机制(依赖于唯一约束或乐观锁定 ),您可以使用悲观锁定。
你需要:
InvoiceSequence表独占锁也将防止并发读和写。
发布于 2015-11-13 19:41:45
序列是一组整数1,2,3,.根据需要按顺序生成。数据库中经常使用序列,因为许多应用程序要求表中的每一行都包含唯一的值,而序列提供了一种生成它们的简单方法。
一种你可以做的方法
class BusinessFactory {
public String createUniqueValue() {
String valueNotUsed = (String) getSession().createSQLQuery("select nextval('hibernate_sequence')");
// generate new value
return newValue;
}}https://stackoverflow.com/questions/33700390
复制相似问题