如何使用Hibernate JPA线程安全进行数据库访问?

时间:2015-01-13 23:08:51

标签: java mysql multithreading hibernate jpa

我想知道我需要做什么才能访问数据库线程安全。

这是我的实体类:

@Entity
@Table(name = "students")
@NamedQuery(name = "Student.getAll", query = "SELECT s FROM Student s")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(length = 32, name = "name")
    private String name;

    // ... constructor, getters and setters, toString ...
}

这是DbService类:

public class DbService {

    public EntityManager em = Persistence
                         .createEntityManagerFactory("MyPersistenceUnit")
                         .createEntityManager();

    public Student add(Student student) {
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        Student studentFromDb = em.merge(student);
        tx.commit();
        return studentFromDb;
    }

    public void delete(long id) {
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.remove(get(id));
        tx.commit();
    }

    public Student get(long id) {
        return em.find(Student.class, id);
    }

    public void update(Student student) {
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        em.merge(student);
        tx.commit();
    }

    public List<Student> getAll() {
        TypedQuery<Student> namedQuery =
                     em.createNamedQuery("Student.getAll", Student.class);
        return namedQuery.getResultList();
    }

}

这是一个与DbService一起使用的类:

public class SomeDbWorker implements Runnable {
    @Override
    public void run() {
        DbService service = new DbService();

        // do something ...
        service.add( ... );
        service.delete( ... );
        service.getAll();
        // ...
    }
}

  1. 是否足以使添加()删除()更新() getAll()方法同步?
  2. 我可以在源代码中创建多个DbService实例吗?或者我只需要创建一个实例吗?
  3. 也许我应该使用单身设计模式?或者使用所有方法使DbService静态化?

2 个答案:

答案 0 :(得分:4)

无需同步任何内容,

entityManager不是threadSafe,旨在为每个工作单元实例化并在之后销毁。

相反,工厂的生产成本很高,应该重复使用

请参阅http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html&#34;应用程序管理的实体经理&#34; 和https://stackoverflow.com/a/22773758/2087640

答案 1 :(得分:-2)

您不需要使这些方法同步,它们是线程安全的。是的,让DbService成为单身人士可能是有意义的。或者,您可以将em设为静态。单身人士是我的偏好。您也不希望em公开。当你在它的时候把它变成私人。