Как реализовать обновление таблицы в БД из разных потоков с помощью DAO на основе Hibernate? - PullRequest
2 голосов
/ 08 ноября 2010

У меня есть класс, назовем его UserGenerator. Он содержит несколько введенных DAO (пружинных синглтон-бобов), скажем, UserDao и OrganizationDao.

Цель

UserGenerator - создание пользователей для новой организации. Итак, что я хочу иметь:

@Transactional
public void createOrganizationWithUsers(Organization org, int userCount) {
    organizationDao.persist(org);
    //run (userCount / 100) threads, let them do something like
    // userDao.persist(new User(randomParams())); 

}

Проблема в том, что организация создана успешно, но userDaos выдает трудно отлаженные исключения, и, как я понимаю, они утверждают, что сеанс Hibernate закрыт (или, может быть, что-то еще):

//this line (only if runs in a new thread) produces the exceptions 
//shown below (it tries to retrieve the organization by its Id)
getSession().createCriteria(getDomainEntityClass()).add(Restrictions.eq("id",id)).uniqueResult();

//Exceptions
org.hibernate.exception.JDBCConnectionException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2235)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2124)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1597)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:328)
...
Caused by: org.postgresql.util.PSQLException: An I/ error occured while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:220)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2232)
    ... 28 more
Caused by: java.net.SocketException: Socket closed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:135)
    at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:104)
    at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73)
    at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:259)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1182)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:194)
    ... 36 more

Как правильно выполнить эту задачу?

P.S. Я знаю, что дизайн далек от совершенства, но мне просто интересно, как достичь цели, даже если стоит перепроектировать систему и избежать проблемы.

1 Ответ

0 голосов
/ 08 ноября 2010

Проблема может быть связана со следующим:

  • Hibernate Session s не являются потокобезопасными
  • Управляемые Spring транзакции связаны с потоками

Итак, я предполагаю, что каждый поток должен начать свою собственную транзакцию (например, с TransactionTemplate) и получить свою собственную Session через SessionFactory.getCurrentSession(). Но обратите внимание, что в этом случае вся операция не будет транзакционной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...