首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事务隔离级别

事务隔离级别
EN

Stack Overflow用户
提问于 2011-07-07 20:57:26
回答 2查看 1.7K关注 0票数 7

我将尝试描述JPA事务隔离级别中的问题。

数据库结构:

  • Table1 -> with PK定义为date ('ddMMyyyy')
  • Table2 -> with FK to Table1

JPA(隔离级别::read_commited) -代码:

代码语言:javascript
复制
    Query query = em.createQuery("from Table1 trd where trd.id = :d");
    query.setParameter("d", date);

    Table1 t = null;
    try{
        t = (Table1) query.getSingleResult();
    }catch(javax.persistence.NoResultException e){
        t = null;
    }

    if(t==null){
        t=new Table1 (date);
        em.persist(trd);
    }

    for(Table2 q:tables2){
        q.setTable1(t);
        em.merge(q);
    }

因此,过程检查该记录是否存在于db中,如果没有,则创建新的记录。如果系统只基于一个线程,则该方法是完全编码的。否则,可能会出现这样的情况:

检查database

  • Thread 2中是否存在按日期表示的实体:执行完全相同的

操作

他们两人都认为这样的记录还没有存在,所以再加上一个新的。在完成交易之前,一切都是正常的。第一项将毫无例外地实行,购买第二项上升例外与主键复制有关。

除了将隔离级别更改为SERIALIZABLE之外,是否有可能保留这种情况?

EN

回答 2

Stack Overflow用户

发布于 2011-07-07 22:00:45

是的,一般来说,隔离级别= SERIALIZABLE应该可以解决您的问题。当将隔离级别更改为最严格的选项时,不要低估副作用。它可能会影响数据库利用率和请求吞吐量。也许您可以在创建T1之后显式提交TRX,然后打开另一个TRX: EntityManager.getTransaction().commit()

您仍然必须捕获重复的键异常。

票数 4
EN

Stack Overflow用户

发布于 2011-07-08 17:48:57

这是数据库在高度并发环境中最难解决的问题之一。最后,唯一真正的解决方案是抓住异常并适当地处理它。

根据您提供的代码,很难判断这可能是什么。如果这是一个webapp,您很可能希望捕获重复的键异常,并向最终用户显示一些有用的消息。比如“这个记录已经创建了”,或者类似的东西。

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

https://stackoverflow.com/questions/6617091

复制
相关文章

相似问题

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