交易隔离级别

psh*_*psh 6 java database hibernate jpa transactions

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

数据库结构:

  • Table1 - >将PK定义为日期('ddMMyyyy')
  • Table2 - >用FK到Table1

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

    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);
    }
Run Code Online (Sandbox Code Playgroud)

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

  • 线程1:检查数据库中是否存在按日期表示的实体
  • 线程2:完全一样

他们俩都认为这样的记录尚不存在,所以加上新记录.在提交交易之前,一切都很好.第一个将被提交,没有任何例外,购买与主键复制相关的第二个上升异常.

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

hom*_*ome 4

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

您仍然需要捕获重复键异常。