Spring 3.0.7 / Hibernate 3.5.0 で作業しています。休止状態のエンティティで動作するコードがいくつかあります。それは正常に動作します。このコードの統合テストを作成しようとすると、問題が発生します。以下は、トランザクションに関してコードがどのようにレイアウトされているかのスキームです。
class EntityDAOImpl implements EntityDAO<T>
{
public T save(T entity)
{
getHibernateTemplate().saveOrUpdate(entity);
}
}
class EntityManagerImpl : implements EntityManager
{
//EntityDAO dao;
@Transactional
public Entity createEntity()
{
Entity entity = dao.createNew();
//set up entity
dao.save(entity);
}
public Entity getFirstEntity()
{
return dao.getFirst();
}
}
コードは 2 つのスレッドで実行されます。
Thread1:
//EntityManager entityManager
entityManager.createEntity();
//enity was saved and commited into DB
Thread thread2 = new Thread();
thread2.start();
//...
thread2.join();
...
Thread2:
//since entity was commited, second thread has no problem reading it here and work with it
Entity entity = entityDao.findFirst();
これで、このコードへの統合テストもできました。そして、ここに問題があります。このテストのトランザクションは、完了後にデータベースの変更を確認したくないため、ロールバックされます。
@TransactionConfiguration(transactionManager="transactionManagerHibernate", defaultRollback=true)
public class SomeTest
{
@Transactional
public void test() throws Exception
{
//the same piece of code as described above is run here.
//but since entityManager.createEntity(); doesn't close transaction,
//Thread2 will never find this entity when calling entityDao.findFirst()!!!!!
}
}
スレッド間で休止状態のセッションを共有することはお勧めできません。この状況に対処するには、どのようなアプローチをお勧めしますか?
私が最初に考えたのは、単純化してスレッド化を回避することでした。しかし、スレッド化はメモリを節約するのに役立ちます。そうしないと、大量のデータをメモリに保持する必要がありました。