我在一个多线程Java应用程序上工作,它是一个提供REST服务的Web服务器,每秒约有1000个请求。我有一个关系数据库,并且使用 hibernate 方式来访问它。该数据库每秒大约有300-400个请求。从多线程的角度来看,我想知道DAO模式是否正确。
因此,有一个BaseModel类看起来像这样:

public class BaseModelDAO
{

    protected Session session;


    protected final void commit() {
        session.getTransaction().commit();
    }


    protected final void openSession() {
        session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
    }

}
然后,我为数据库中的每个表都有一个DAO类:
public class ClientDAOHibernate extends BaseModelDAO implements ClientDAO
{

    private Logger log = Logger.getLogger(this.getClass());

    @Override
    public synchronized void addClient(Client client) throws Exception {
        try {
            openSession();
            session.save(client);
            commit();
            log.debug("client successfully added into database");
        } catch (Exception e) {
            log.error("error adding new client into database");
            throw new Exception("couldn't add client into database");
        } finally {
            session.close();
        }
    }

    @Override
    public synchronized Client getClient(String username, String password) throws Exception {
        Client client = null;
        try {
            openSession();
            client = (Client) session.createCriteria(Client.class).createAlias("user", "UserAlias").add(Restrictions.eq("UserAlias.username", username)).add(Restrictions.eq("UserAlias.password", password)).uniqueResult();
            commit();
        } catch (Exception e) {
            log.error("error updating user into database");
            throw new DBUsersGetUserException();
        } finally {
            session.close();
        }
        return client;
    }
}
这是我的问题:
  • 考虑到并发请求的数量,每次访问db都可以打开和关闭 session 吗?
  • 现在,可以直接从应用程序业务逻辑访问DAO类。应该由DAO管理员来安装吗?如果是,执行该设计应该是一个好的设计吗?
  • 最佳答案

    不,您的实现不是一个好方法:

  • 事务应该围绕业务逻辑,而不是数据访问逻辑:如果您想将钱从一个帐户转移到另一个帐户,则不能有一个用于借记操作的交易,而不能有另一个用于贷记操作的交易。交易必须涵盖整个用例。
  • 通过同步DAO的每个方法,可以禁止两个请求同时获取一个客户端。您的DAO中不应包含 session 字段。 session 应该是每种方法的局部变量。这样,您的DAO将变为无状态,因此从本质上讲是线程安全的,而无需任何同步
  • 正如Michael在他的评论中所说,使用程序化事务会使代码变得冗长,复杂且不针对业务用例。使用EJB或Spring享受声明式事务管理和异常处理。
  • 关于java - DAO模式多线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11817872/

    10-09 07:17
    查看更多