私は、Hibernate(4.1.9.Final)とMySQL(14.14按分5.5.29、InnoDBのテーブル)でめちゃくちゃ奇妙な結果を得る:休止/ MySQLの同時実行の問題
は、私が使用してデータベースに何かを持続あるスレッドで別のスレッドを使ってフェッチしようとすると、Hibernateは必ずしもそのエンティティを見つけるとは限りません。 (私は適切にトランザクションをコミットし、負荷のセッションを開く前に持続セッションを閉じていたという事実にもかかわらず。)
いくつかの所見:
私はがシングルを使用して、これを再現することはできませんスレッドプログラム。
私は、データベース内の「行方不明」の実体を見ることができ、そして
私は、アプリケーションがが成功したエンティティをロードすることができます休止状態再起動した場合
。
ここに問題を示すSSCCEがあります。 (輸入は簡潔にするために省略):
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; }
}
プロデューサークラスが(DummyEntities
を作成し、それを持続します)。
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);
}
}
}
Consumerクラス(データベースからロードDummyEntities
):
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);
}
}
}
は最後に、ここにDummyEntity
のマッピング-XMLです。
Entity with id -225971146115345 NOT FOUND
任意のアイデア理由:
<?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>
結果の出力は常にのようなもので終わりますか?
(これは前questionの洗練されたバージョンです。)
これまでの質問に答えてくれましたが、それをチェックしてください。 – didierc
@aioobe hibernateおよび/またはMySQLの他のバージョンについては – Eugene
@Eugene、それはHibernateの問題ではないと思います。他のMySQLバージョンは手元にありません。私がPostgreSQLに変更すると、すべて正常に動作します。 – aioobe