dostaję szalenie dziwny wynik z hibernacji (4.1.9.Final) i MySQL (14,14 Distrib 05.05.29, tabela InnoDB):Hibernate/MySQL problem współbieżności
Kiedy utrzymują coś do bazy danych za pomocą jeden wątek i spróbuj go pobrać za pomocą innego wątku, Hibernate nie zawsze znajduje obiekt.
Niektóre obserwacje (pomimo faktu, że ja właściwie popełniającego transakcję i zamykanie utrzymywać sesję przed otwarciem obciążenia sesję.):
I nie można odtworzyć to za pomocą pojedynczego -tyty program.
I może zobaczyć „brakującą” podmiot w bazie danych, a
Gdybym ponownie uruchomić aplikację hibernacji może pomyślnie załadować podmiot.
Oto SSCCE ilustrujące problem. (Import pominięta dla zwięzłość):
public class StressTest {
static SessionFactory sessionFactory;
public static void main(String[] args) throws InterruptedException,
ExecutionException {
// Configure Hibernate
Configuration conf = new Configuration();
conf.setProperty("hibernate.dialect",
"org.hibernate.dialect.MySQLInnoDBDialect");
conf.configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(conf.getProperties())
.buildServiceRegistry();
sessionFactory = conf.buildSessionFactory(serviceRegistry);
// Set up producer/consumer
BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>();
new Consumer(queue).start();
new Producer(queue).start();
}
}
class DummyEntity {
long id;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
}
klasa Producent (tworzy DummyEntities
i utrzymuje je).
class Producer extends Thread {
BlockingQueue<Long> sink;
public Producer(BlockingQueue<Long> sink) {
this.sink = sink;
}
@Override
public void run() {
try {
while (true) {
Session session = StressTest.sessionFactory.openSession();
DummyEntity entity = new DummyEntity();
entity.setId(new Random().nextLong());
session.beginTransaction();
session.save(entity);
session.getTransaction().commit();
session.close();
sink.put(entity.getId());
}
} catch (InterruptedException ignore) {
System.exit(-1);
}
}
}
klasa Konsumentów (ładunki DummyEntities
z bazy danych):
class Consumer extends Thread {
BlockingQueue<Long> source;
public Consumer(BlockingQueue<Long> source) {
this.source = source;
}
@Override
public void run() {
try {
while (true) {
long entityId = source.take();
Session session = StressTest.sessionFactory.openSession();
Object entity = session.get(DummyEntity.class, entityId);
session.close();
if (entity == null) {
System.err.printf("Entity with id %d NOT FOUND", entityId);
System.exit(-1);
}
}
} catch (InterruptedException ignore) {
System.exit(-1);
}
}
}
Wreszcie, oto mapping-xml dla DummyEntity
.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
default-cascade="all"
default-lazy="false">
<class name="se.stresstest.DummyEntity">
<id name="id" type="long">
<generator class="assigned"/>
</id>
</class>
</hibernate-mapping>
Wynikiem zawsze kończy się coś takiego:
Entity with id -225971146115345 NOT FOUND
jakieś pomysły dlaczego?
(Jest to wyrafinowana wersja poprzedniej question.)
Podałem odpowiedź na poprzednie pytanie, które również pasuje do tego pytania, proszę je sprawdzić. – didierc
@ aioobe a co z innymi wersjami hibernacji i/lub MySQL – Eugene
@Eugene, nie sądzę, że jest to problem Hibernacji i nie mam pod ręką innych wersji MySQL. Jeśli zmienię na PostgreSQL, wszystko działa poprawnie. – aioobe