Будет ли использование синхронизации на Java DAO вызывать проблемы? - PullRequest
2 голосов
/ 10 июля 2009

Будет ли использование ключевого слова «synchronized» в методах Java DAO вызывать проблемы при использовании веб-приложением?

Я спрашиваю, потому что у меня есть многопоточное автономное приложение, которому необходимо синхронизировать методы, чтобы избежать конфликта ресурсов, как показано здесь.

java.util.concurrent.ExecutionException: javax.persistence.PersistenceException: org.hibernate.HibernateException: Found shared references to a collection: com.replaced.orm.jpa.Entity.stuffCollection

Что меня беспокоит, так это то, что, когда значительное количество людей пытается использовать приложение, синхронизированные методы блокируют и замедляют работу всего приложения.

Я использую фабрику диспетчера сущностей в JPA, которая предоставляет диспетчер сущностей для DAO. Я мог бы технически удалить слой DAO и заставить классы напрямую вызывать фабрику диспетчера сущностей, но мне нравится разделение, которое обеспечивает DAO.

Я должен также отметить, что я очень осторожен, чтобы не передавать объекты ORM связанных сущностей между потоками. Я предполагаю, что ошибка доступа к ресурсам возникает при доступе к DAO. Я думаю, что несколько потоков идут одновременно и пытаются сохранить или прочитать из базы данных неатомарными способами.

В этом случае использование DAO принесет больше вреда, чем помощи?


Большая часть информации, которую я не упомянул, состоит в том, что DAO не является единичным. Если бы я думал достаточно ясно, чтобы включить эту деталь, я бы, вероятно, не задавал вопрос в первую очередь.

Если я правильно понимаю, Spring создает новый экземпляр класса DAO для каждого класса, который его использует. Таким образом, управляющий объект должен быть уникальным для каждого потока. Ключевым моментом здесь, как ответил Роб Х, является отсутствие общего доступа к менеджеру сущностей.

Однако теперь я не понимаю, почему я получаю ошибки при удалении синхронизированных.


В соответствии с этим потоком аннотация @PersistenceContext создает поточно-ориентированный SharedEntityManager. Таким образом, вы должны иметь возможность создавать синглтон DAO.

Ответы [ 2 ]

2 голосов
/ 10 июля 2009

Вы говорите, что не разделяете объекты сущности между потоками. Это хорошо. Но вы также должны убедиться, что вы не разделяете EntityManager объекты (или Session объекты в Hibernate) между потоками. Фреймворки, такие как Spring, управляют этим автоматически, сохраняя сеанс в локальной переменной потока. Если вы кодируете свои собственные DAO без помощи фреймворка, вам нужно принять меры предосторожности, чтобы не делиться ими.

После того, как вы это сделаете, не должно быть причин для синхронизации методов DAO, поскольку ни одно из диалоговых состояний не будет разделено между потоками. Это очень важно для высококонкурентного веб-приложения. Альтернативой является то, что только один поток сможет одновременно получить доступ к DAO, при условии, что все они используют один и тот же экземпляр DAO. Совсем плохо для пропускной способности.

1 голос
/ 10 июля 2009

Если это необходимо синхронизировать для обеспечения безопасности потоков, оставьте их там. В любом случае в этом случае требуется блокировка. Если для случая веб-приложения блокировка не требуется, вы можете:

  • оставить как есть, так как производительность ударить, когда нет спора о блокировка незначительна, и незначительный, если принять во внимание за счет попадания в базу.
  • Перепроектируйте его так, чтобы вы добавили уровень синхронизации для случай отдельного приложения, которое защищает основную несинхронизированный DAO.

Лично я бы оставил все как есть и профилировал бы, чтобы увидеть, нужно ли вам проводить рефакторинг. До этого вы просто делаете преждевременную оптимизацию.

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