DAO模式多线程

时间:2012-08-05 16:00:33

标签: java multithreading design-patterns dao

我从事多线程Java应用程序,它是一个提供REST服务的Web服务器,每秒大约1000个请求。我有一个关系数据库,我使用hibernate来访问它。该数据库每秒约有300-400个请求。从多线程的角度来看,我想知道DAO模式是否正确。

因此,有一个BaseModel类看起来像这样:

  

公共类BaseModelDAO {

protected Session session;


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


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

}

然后我为数据库中的每个表都有一个DAO类:

  

公共类ClientDAOHibernate扩展BaseModelDAO实现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;
}

}

以下是我的问题:

  1. 考虑到并发请求的数量,可以为每次访问db打开和关闭会话吗?

  2. 现在可以直接从应用程序业务逻辑访问DAO类。应该用DAO经理上网吗?如果是的话,实施它应该是一个好的设计?

1 个答案:

答案 0 :(得分:9)

不,你的实施不是很好:

  • 交易应围绕业务逻辑,而不是数据访问逻辑:如果您想将资金从一个帐户转移到另一个帐户,您就不能进行借记操作的交易,也不能进行信用操作的另一笔交易。该交易必须涵盖整个用例。
  • 通过同步DAO的每个方法,您禁止两个请求同时获取客户端。您的DAO中不应该有会话字段。会话应该是每个方法的局部变量。通过这样做,您的DAO将变为无状态,因此本质上是线程安全的,无需任何同步
  • 正如Michael在评论中所说,使用程序化事务会使代码冗长,复杂,而不是专注于业务用例。使用EJB或Spring来享受声明式事务管理和异常处理。