1
나는 부모가있다.최대 절전 모드, @ManyToOne 삽입하고, EHCache는
이 같은 대략 간다 코드에서, 부모에 대한 업데이트를 처리 해요 :
- 부모
- 가에서 검색 받기 (순서대로 -으로 Ehcache, DB, 또는 발견되지 않는 경우는 작성)
- 프로세스는 업데이트, 부모에 아이를 만드는 DB에
- 저장을 찾을 수없는 경우
- S 캐시에 찢어
를 통해 실행하면, 다음과 같은 순서
- 첫 번째 업데이트가 완료 발생 찾을 - 부모에게 & 모두가 캐시
- 두 번째 업데이트를 만든 아이 - 캐시에서 검색 부모를, 새를 아이는 두 번째 업데이트가 완료되면, 아이의 ID가 여전히 null의
- 추가됩니다. 그러나 업데이트 은을 성공적으로 완료했습니다. 다시 삽입되는 제 2 Update에서 아이로,
DataIntegrityViolationException
발생합니다 -
- 추가됩니다. 그러나 업데이트 은을 성공적으로 완료했습니다. 다시 삽입되는 제 2 Update에서 아이로,
- 세 번째 업데이트 (최대 절전 로그 및 DB 모두에 대해 확인).
데이터베이스에서 반환되는 것이 아니라 부모가 캐싱된다는 사실과 관련이 있다고 가정합니다. 여기에 올바른 프로세스가 무엇인지 확신 할 수 없습니다.
관련 정보 : <
- 학부모 -> 아이 다시 참조가 올바르게 정의 및 주석된다.
- 부모의 초기 삽입 한 후, 나는 그것을하지 않았다 --- 그것은 차이를 만들어 있는지 확인하기 위해, 다시 가져오고 DB에서 부모를, 캐싱이 시도했습니다. 이 처음
@Transactional
로 주석하고 내 테스트에서 실패하지 않았다으로 - 트랜잭션 경계는 여기에 역할을해야합니다. (A 교훈은 하드 배웠)
무슨 이득이 처리하는 올바른 방법 - 아직도 가진 아이 엔티티가 제대로 추적하면서 특히, DB를마다의 부모를로드하는 것을 방지 할 수 있습니까?
코드의 예는 다음과 같습니다.
@Entity // Parent
class Fixture {
@OneToMany(cascade=CascadeType.ALL, mappedBy="fixture", fetch=FetchType.EAGER) @Getter @Setter
@MapKey(name="instrumentPriceId")
private Map<String,Instrument> instruments = Maps.newHashMap();
private Instrument addInstrument(Instrument instrument)
{
instruments.put(instrument.getInstrumentPriceId(), instrument);
instrument.setFixture(this);
log.info("Created instrument {}",instrument.getInstrumentPriceId());
return instrument;
}
/**
* Returns an instrument with the matching instrumentId.
* If the instrument does not exist, it is created, appended to the internal collection,
* and then returned.
*
* This method is guaranteed to always return an instrument.
* This method is thread-safe.
*
* @param instrumentId
* @return
*/
public Instrument getInstrument(String instrumentId)
{
if (!instruments.containsKey(instrumentId))
{
addInstrument(new Instrument(instrumentId));
}
return instruments.get(instrumentId);
}
}
@Entity // Child
public class Instrument {
@Column(unique=true)
@Getter @Setter
private String instrumentPriceId;
@ManyToOne(optional=false)
@Getter @Setter @JsonIgnore
private Fixture fixture;
public Instrument(String instrumentPriceId)
{
this.instrumentPriceId = instrumentPriceId;
}
}
그리고, 업데이트 프로세서 코드 :
class Processor {
@Autowired
@Qualifier("FixtureCache")
private Ehcache fixtureCache;
@Autowired
private FixtureRepository fixtureRepository;
void update(String fixtureId, String instrumentId) {
Fixture fixture = getFixture(fixtureId);
// Get the instrument, creating it & appending
// to the collection, if it doesn't exist
fixture.getInstrument(instrumentId);
// do some updates...ommitted
fixtureRepository.save(fixture);
fixtureCache.put(new Element(fixtureId, fixture));
}
/**
* Returns a fixture.
* Returns from the cache first, if present
* If not present in the cache, the db is checked.
* Finally, if the fixture does not exist, a new one is
* created and returned
*/
Fixture getFixture(String fixtureId) {
Fixture fixture;
Element element = fixtureCache.get(fixtureId);
if (element != null)
{
fixture = element.getValue();
} else {
fixture = fixtureRepostiory.findOne(fixtureId);
if (fixture == null)
{
fixture = new Fixture(fixtureId);
}
}
return fixture;
}
}