1

我在一个多线程 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;
    }
}

以下是我的问题:

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

  2. 现在可以直接从应用程序业务逻辑访问 DAO 类。应该使用 DAO 管理器安装吗?如果是,什么应该是一个好的设计来实现它?

4

1 回答 1

10

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

  • 交易应该围绕业务逻辑,而不是围绕数据访问逻辑:如果你想将钱从一个账户转移到另一个账户,你不能有一个借方操作的交易,而另一个贷方操作的交易。事务必须涵盖整个用例。
  • 通过同步 DAO 的每个方法,您可以禁止两个请求同时获取一个客户端。你的 DAO 中不应该有会话字段。session 应该是每个方法的局部变量。通过这样做,您的 DAO 将变得无状态,因此本质上是线程安全的,无需任何同步
  • 正如 Michael 在他的评论中所说,使用程序化事务会使代码冗长、复杂,并且不专注于业务用例。使用 EJB 或 Spring 享受声明式事务管理和异常处理。
于 2012-08-05T18:23:20.640 回答