Java 使用此aproach时会出现线程安全问题吗?

Java 使用此aproach时会出现线程安全问题吗?,java,hibernate,jpa,thread-safety,ejb,Java,Hibernate,Jpa,Thread Safety,Ejb,我正在使用EJB/JPA,并创建了一个名为createDataset的静态方法,该方法将查找Dataset对象。每次必须插入、更新、删除实体时,我都会检索一个调用DatasetFactory.createDataset()的DatasetObject,并调用相应的方法(insert、update等) 代码: public class DatasetFactory { public static Dataset createDataset() { try {

我正在使用EJB/JPA,并创建了一个名为createDataset的静态方法,该方法将查找Dataset对象。每次必须插入、更新、删除实体时,我都会检索一个调用DatasetFactory.createDataset()的DatasetObject,并调用相应的方法(insert、update等)

代码:

public class DatasetFactory {
    public static Dataset createDataset() {
        try {
            return (Dataset) new InitialContext().lookup("java:global/.../Dataset");
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

public interface Dataset<T> {
    void insert(T entity);
    //...
}

@Stateless
@EJB(name = "java:global/.../Dataset", beanInterface = Dataset.class)
public class DatasetBean<T> implements Dataset<T> {

    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    private EntityManager entityManager;

    @Override
    public void insert(T entity) {
        entityManager.persist(entity);
    }
    //...
}
公共类数据集工厂{
公共静态数据集createDataset(){
试一试{
返回(数据集)new InitialContext().lookup(“java:global/../Dataset”);
}捕获(例外情况除外){
抛出新的运行时异常(ex);
}
}
}
公共接口数据集{
无效插入(T实体);
//...
}
@无国籍
@EJB(name=“java:global/../Dataset”,beanInterface=Dataset.class)
公共类DatasetBean实现Dataset{
@PersistenceContext(类型=PersistenceContextType.TRANSACTION)
私人实体管理者实体管理者;
@凌驾
公共无效插入(T实体){
entityManager.persist(实体);
}
//...
}
使用此aproach时会出现线程安全问题吗?如果是,我应该做什么修改?我是否应该将同步修改器放在DatasetFactory.createDataset()中


非常感谢

如果您的entitymanager是线程保存,那么使用插入方法就没有风险

如果您的entitymanager是线程保存,那么使用插入方法就没有风险

从线程安全的角度来看,您的代码看起来不错


但是看起来您正在实现一个DAO(数据访问对象),只是将DAO称为数据集,使用EJB作为EJB容器加载并在启动时验证所有EJB并不是一个好主意,这可能会降低速度。通常EJB在内存(EJB池)中只保留一定数量的EJB,但是如果您不将DAO实现为EJB,您可以创建任意数量的EJB,Java的GC会为您清理它们。

从线程安全的角度来看,您的代码看起来不错


但是看起来您正在实现一个DAO(数据访问对象),只是将DAO称为数据集,使用EJB作为EJB容器加载并在启动时验证所有EJB并不是一个好主意,这可能会降低速度。通常EJB在内存中只保留一定数量的EJB(EJB池),但是如果您不将DAO实现为EJB,您可以创建任意数量的EJB,Java的GC会为您清理它们。

您不必同步EJB的任何方法,因为EJB规范指定EJB实例不能由两个并发线程调用。EJB容器为您处理同步和线程安全。这是使用EJB的要点之一。

您永远不必同步EJB的任何方法,因为EJB规范指定EJB实例不能由两个并发线程调用。EJB容器为您处理同步和线程安全。这是使用EJB的要点之一。

entityManager不是线程安全的,但是EJB可能永远不会被两个woncurrent线程调用,所以这不是问题。entityManager不是线程安全的,但是EJB可能永远不会被两个woncurrent线程调用,所以这不是问题。@joaosavio如果您将容器配置为,最多创建5个bean实例,但超过5个用户同时使用您的应用程序,您可能会遇到一些性能问题(饥饿)。然而,我在回答中提到的是,当你的应用服务器启动时,它应该创建并验证你的所有EJB,这会减慢“启动时间”,而不是运行中的应用程序的性能。@joaosavio如果你将容器配置为(比如)最多创建5个bean实例,但同时有5个以上的用户使用你的应用程序,您可能会遇到一些性能问题(饥饿)。然而,我在回答中提到的是,当应用程序服务器启动时,它应该创建并验证所有EJB,这会减慢“启动时间”,而不是运行应用程序的性能。