首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在读写操作之间锁定表

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

Stack Overflow用户
提问于 2015-11-13 19:28:07
回答 2查看 3.7K关注 0票数 4

我有这样一种情况,即每条新记录都应该包含一个唯一的、可读的值。此值对用户具有业务意义,并将作为数据库中的自然id (主键旁边)处理。

给你一个价值结构的概念:

代码语言:javascript
复制
 - 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'
   ...

这个商业价值是由一个工厂创造的:

代码语言:javascript
复制
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;
    }

}

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

代码语言:javascript
复制
  @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中做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-15 15:15:59

不使用冲突检测并发控制机制(依赖于唯一约束或乐观锁定 ),您可以使用悲观锁定。

你需要:

  1. 一个具有映射到它的实体的InvoiceSequence
  2. 此表只有一行,存储最新的发票序列值。
  3. 获取独占锁在记录中: InvoiceSequence invoiceSequence = em.find(InvoiceSequence.class,1L,LockModeType.PESSIMISTIC_WRITE)
  4. 使用业务逻辑增加序列,并修改实体以存储最新值: 字符串currentSequence = invoiceSequence.getValue();字符串nextSequence = sequenceGenerator.nextValue(currentSequence);invoiceSequence.setValue(nextSequence);

独占锁也将防止并发读和写。

票数 6
EN

Stack Overflow用户

发布于 2015-11-13 19:41:45

序列是一组整数1,2,3,.根据需要按顺序生成。数据库中经常使用序列,因为许多应用程序要求表中的每一行都包含唯一的值,而序列提供了一种生成它们的简单方法。

一种你可以做的方法

代码语言:javascript
复制
class BusinessFactory {
public String createUniqueValue() {
    String valueNotUsed = (String) getSession().createSQLQuery("select nextval('hibernate_sequence')");    

   // generate new value 

   return newValue;
}}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33700390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档