我可以使用这种方法遇到线程安全问题吗?

时间:2012-01-07 20:09:42

标签: java hibernate jpa thread-safety ejb

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

代码:

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);
    }
    //...
}

使用此方法可以解决线程安全问题吗?如果是这样,我应该做些什么修改?我应该将synchronized修饰符放在DatasetFactory.createDataset()?

非常感谢!

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

如果您的entitymanager是线程保存,则使用您的insert方法没有风险