2

我正在使用 Hibernate在Jboss5上运行的 Web 应用程序中实现 DAO 层(Sybase DB)

我面临的问题是当客户端/用户界面同时进行多个 HTTP 调用时——这反过来又调用 DAO 插入方法——存在竞争条件,导致两个调用几乎同时运行 DAO 插入方法。我真正想要的是

  1. 第一个请求调用 DAO 方法
  2. 第一个请求读取当前数据库值
  3. 根据当前 db 值检查新数据是否有效
  4. 如果有效,则插入新值
  5. 然后是第二个读取当前数据库值的请求
  6. 检查新数据是否有效
  7. 如果有效,则插入值...如果有更多调用,依此类推

我的 DAO 层代码如下所示:

@Override
@Transactional
public Set<PartyData> insertPartyData(final Set<PartyData> pData) throws DataServiceException
{
    sessionFactory.getCurrentSession().getTransaction().begin();
    //code to read the current db value
    //validation code to check if new value can be inserted based on what's currently in db
    sessionFactory.getCurrentSession().save(pData);
    sessionFactory.getCurrentSession().getTransaction().commit();
}

问题?

如何确保数据库在一个事务期间锁定表,以便任何其他请求等到前一个事务完成?

4

3 回答 3

0

虽然锁定表格会起作用 - 锁定整个表格的过程似乎并不正确。必须有其他方法来完成您正在尝试做的事情,例如独特的约束。

于 2013-07-26T10:25:46.450 回答
0

* 回答 *

好的,我已经尝试了以下似乎到目前为止有效的解决方案。

似乎发生的是每个请求似乎都创建了一个新会话,并且该会话在其自己的事务中运行。因此,似乎没有两个请求相互干扰,并且每个事务一次运行。

我不是休眠专家,所以如果这不是正确的方法,请纠正我。

@Override
@Transactional
public Set<PartyData> insertPartyData(final Set<PartyData> pData) throws DataServiceException
{
    final Session session = sessionFactory.openSession();
    Transaction tx;
    try {
        tx = session.beginTransaction();
        \\read curren db value and do the validation with new data (throw exception if validation fails else continue)
        session.save(pData);
        }
        tx.commit();
    }
    catch (final Exception e) {
        throw new DataServiceException(e);
    }
    finally {
        session.close();
    }
    return pData;
}
于 2013-07-26T10:48:00.427 回答
0

IMO最好在容器级别而不是应用程序级别完成(不知道它是否甚至可以在应用程序级别完成)。

根据这篇文章,你可以通过在Connector中配置两个属性来做你喜欢的事情。

设置maxThreads为 1 ( maxThreads: The maximum number of request processing threads to be created by this connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 200.)

这将确保您每次只运行一个请求。

增加acceptCount: ( acceptCount: The maximum queue length for incoming connection requests, when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 10.)

这应该设置得相对较高,这样您就不会拒绝与您的服务的连接,而是将其添加到队列中,直到另一个请求完成执行。

于 2013-07-26T10:55:45.210 回答