@ ApplicationScoped CDI bean i @PersistenceContext - czy to bezpieczne ?
Czy można zrobić coś takiego z CDI?
@Named
@ApplicationScoped
public class DAO {
@PersistenceContext
private EntityManager entityManager;
}
Rozumiem, że EntityManager
samo w sobie nie jest bezpieczne dla wątków i dlatego nie powinno być używane we wspólnym globalnym kontekście, takim jak @ApplicationScoped
. Jednakże, ponieważ obiekt iniekcyjny {[3] } jest w rzeczywistości owijarką świadom wątku wokół bazowego EntityManager
, Czy to sprawia, że jest to w porządku?
Widziałem inne posty na ten temat, ale nie byłem w stanie znaleźć wiarygodnej odpowiedzi na ten konkretny przypadek. Na przykład:
Java CDI @PersistenceContext and thread safety
Wygląda na to, że jest bezpieczny w użyciu z @Stateless
, na przykład - ale nie jestem pewien, czy to ze względu na sposób działania @Stateless
, czy z powodu czegoś wewnętrznego do @PersistenceContext
.
EDIT
Źródłem mojego zamieszania jest to, że opakowanie @PersistenceContext
injected EntityManager
zdaje się być świadome bieżącego wątku, aby dowiedzieć się, czy jest już transakcja w toku. Więc może jestem mylenie nić-świadomość z nić-Bezpieczeństwo i są to dwie różne rzeczy.
1 answers
Jestem prawie pewien, że w tym przypadku CDI nie tworzy kontekstowego proxy dla menedżera jednostek. W końcu, w jakim zakresie to będzie? Możesz chcieć czegoś podobnego do hipotetycznego @ThreadScoped
lub po prostu @RequestScoped
, ale @PersistenceContext
nie jest adnotacją CDI i CDI nie modyfikuje swojej semantyki.
Więc to, co się tutaj dzieje, to wstrzyknięcie "managed bean" platformy Java EE 6, które jest podobne do wstrzykiwania menedżera entity w Servlet. Oba przypadki dają wystąpienie, które nie jest bezpieczne w użyciu bezpośrednio.
To ze względu na sposób działania. Każde żądanie (wywołanie) metody w bezstanowej bean jest kierowane przez kontener do unikalnej instancji. Pojemnik gwarantuje, że żadne dwa wątki nie są aktywne w tej samej fasoli.Wygląda na to, że jest bezpiecznie używać z @Stateless, na przykład - ale nie jestem pewien, czy to ze względu na sposób działania @Stateless, czy z powodu czegoś nieodłącznego do @PersistenceContext.
Z CDI można uzyskać podobnie jak w przypadku żądania poprzez umieszczenie menedżera encji w zakresie żądania i wstrzyknięcie go do zakresu aplikacji:
import javax.enterprise.context.RequestScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@RequestScoped
public class EntityManagerProvider {
@PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
}
Inject this into the bean where you previously injected the entity manager:
@Named
@ApplicationScoped
public class DAO {
@Inject
private EntityManagerProvider entityManagerProvider;
}
To da ci unikalnego menedżera jednostek na żądanie. Możesz łatwo przekształcić to również w metodę producer, więc nie będziesz musiał dzwonić getEntityManager()
do wstrzykniętego dostawcy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-15 14:47:31