2013-07-26 37 views
1

我使用Hibernate来实现对运行Jboss5一个Web应用程序的DAO层(DB的Sybase)我如何检查DB是交易之间的锁定

我面临的问题是当客户端/用户界面多次同时进行HTTP调用时(这反过来又会调用DAO插入方法)会导致两个调用在几乎相同的时间运行DAO插入方法。我真正想要的是

  1. 第1请求调用DAO方法
  2. 1请求读取当前的分贝值
  3. 检查如果基于当前的分贝值
  4. 如果有效的新数据是有效的,插入新的价值
  5. ,然后第二个请求读取当前dB值
  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(); 
} 

问题?

如何确保数据库在一个事务的持续时间内锁定表,以便任何其他请求等到上一个事务完成时才会等待?

+0

你使用什么web容器? – MaVRoSCy

+0

Web容器 - Jboss5 – kapricanon

+0

您正在使用哪些DBMS? Postgres的?甲骨文? –

回答

0

*答案*

好吧我曾尝试以下解决方案,它似乎至今已经奏效。

什么似乎发生每个请求似乎创建一个新的会话,该会话运行在自己的事务。所以没有两个请求似乎互相干扰,每个事务一次运行。

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

@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; 
} 
+0

不要忘记,你可以接受你自己的答案.. – MaVRoSCy

+0

是的,但它说我只能在2天后做到这一点??是这样吗? – kapricanon

+0

啊,是的,这是正确的 – MaVRoSCy

0

虽然锁定表将工作 - 锁定整个表的过程似乎并不正确。必须有其他方式来完成你想要做的事情,比如独特的限制。

+1

这不提供问题的答案。要批评或要求作者澄清,在他们的帖子下留下评论 - 你总是可以评论你自己的帖子,一旦你有足够的[声誉](http://stackoverflow.com/help/whats-reputation),你会能够[评论任何帖子](http://stackoverflow.com/help/privileges/comment)。 –

+0

@ kapricanon:您的解决方案是不可扩展的,因为群集环境不可用。 为什么不试试我的答案? – ChanceLai

+0

@ChanceLai - 不能使用唯一约束,因为数据验证(我的问题中的第3点)不像检查重复数据那样简单,有一些更复杂的逻辑来检查某些值的存在并且它们不存在允许插入某些新值。还有其他建议吗? – kapricanon

0

IMO这是最好的容器级别而不是应用程序级别(不知道它可能甚至在应用层面做)做。

基于此article,您可以通过在连接器中配置两个属性来做你喜欢的事情。

设置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.

这应该被设定得比较高,这样你就不会拒绝你的服务连接,而随后添加到队列,直到另一个请求执行完毕。

+0

对不起,我应该提到我们在共享和高度控制的生产环境中运行。所以改变集装箱层面的任何设置都是不可能的。 – kapricanon

+0

这很好,一个连接器可以设置为仅对您的应用程序有效(port,bindAddress) – MaVRoSCy

+0

所以我正确地说如果我将maxThreads设置为1,我的应用程序将一次只能处理一个请求?如果是的话,这个基石会放慢用户体验。 – kapricanon