2014-10-23 2 views
1

У меня есть таблица в MySQL как этотJava Hibernate MySql Таблица Запирание

Таблица аккумуляторе, которые имеют что-то вроде этого.

id-> autoIncrement. 
year->int(11) 
key->varchar(255) 
value(int 11) 

поведение этой таблицы - только одно значение за год, а для ключа - что-то вроде этого.

ID YEAR KEY  VALUE 
1 2014 STOCK 13 
2 2014 QUOTE 10 
3 2014 INVOICE 20 

эти значения не допускаются.

ID YEAR KEY  VALUE 
1 2014 STOCK 13 
2 2014 QUOTE 10 
3 2014 STOCK 20 

Мы не можем иметь две записи с одинаковым YEAR и KEY

У меня есть метод DAO, как это.

public Accumulator get(final String key,final Integer year) 
{ 
    final Session session = currentSession(); 
    final org.hibernate.Query query= session 
      .getNamedQuery("findAccumulatorByKeyAndYear") 
      .setParameter("key",key) 
      .setParameter("year",year) 
    query.setLockOptions(LockOptions.UPGRADE) 
     .setResultTransformer(transformer(clazz)); 
    return (Acumulator)query.uniqueResult(); 
} 

Который вызывается из Manager method

all this happens in the same Hibernate Session 
public int getAccumulator(final String key,final Integer year) 
{ 
    Accumulator accumulator = this.dao.get(key,year); 
    if (accumulator==null)//is not found 
    {      
     final Accumulator newAccumulator = new Accumulator();//create the new Accumulator with key and year 
     newAccumulator.setKey(c01); 
     newAccumulator.setYear(year); 
     newAccumulator.setValue(0);   
     this.save(newAccumulator);  
     return newAccumulator.getValue();//we return the new Value of the record which is 0 in this case 
    } else 
    {//this is working OK. 
     accumulator.setC03(accumulator.getValue()+1);//if exist we add one to value... 
     dao.incrementWithHQL(accumulator);//update in DB. 
     return accumulator.getValue();//return new Value 
    }  
} 

этой подпрограммы вызов с полом-низкого параллелизма проблема возникает в этом случае ..

Accumulator accumulator = this.dao.get(key,year); 
    if (accumulator==null)//is not found 
    {      
     final Accumulator newAccumulator = new Accumulator();//create the new Accumulator with key and year 
     newAccumulator.setKey(c01); 
     newAccumulator.setYear(year); 
     newAccumulator.setValue(0);   
     this.save(newAccumulator);//we schedule to save into the DB.   
     return newAccumulator.getValue();//we return the new Value of the record which is 0 in this case 
    } 

проблема уникальные строки тех которые [KEY, YEAR] получают дубликаты, а затем мы получаем NONUNIQUERESULTEXCEPTION

Я думаю, что проблема есть.

* Check if exist on the DB is not found and schedule to save on commit. 
* Another thread in a different **Hibernate session** reads and not found a `Accumulator` for the same key,year and also schedule a save into DB. 
* Both records are being save. 
* Later any thread try to read if exist a Accumulator for [key,year] and now it got 2. and `NONUNIQUERESULTEXCEPTION` exception is throw. 

UPGRADE замок работает, когда существует запись на BD заморозить ряд до сделки, совершение но WIDE OPEN для выбирает ...

, как это можно сделать, как мой ACCUMULATORS уникальны для моего Клавиша [KEY, YEAR].

любая помощь очень ценим

приветы из Венесуэлы ..

ответ

1

Лучший способ добиться этого, сделать UniqueKey ограничение на БД на [Key, год].

2

Вы можете создать составной ключ год и ключ что-то вроде ниже

@Embeddable 
public class AccumaltorCompositeKey { 

    @Column(name = "ACC_YEAR") 
    private int year; 

    @Column(name = "ACC_KEY") 
    private String key; 

    //getter, setter methods 
} 

@Entity 
@Table(name = "Accumalator") 
public class Accumalator { 

    @EmbeddedId 
    private AccumalatorCompositeKey accumaltorCompositeKey; 

    /*setter getter methods */ 
} 
Смежные вопросы