0

我有一个服务,它根据输入返回一个持久的 Schedule 对象:日期。我有多个线程调用此方法,我想确保唯一性。我不想发现违反约束并给任何用户一个错误。我需要的是:如果一个线程调用该方法并且该日期不存在 Schedule 对象,则该线程创建它并且其他线程等待。在我使用 Spring 之前,只是在我的网络应用程序中使用简单的 Hibernate,我已经通过以下方式完成了它:

我在休眠中使用了 ManagedSessionContext。我在每个 Web 请求的开头开始了一个事务,并在最后提交了它。对于同步块,我立即在同步块中提交了当前事务并启动了一个新事务来完成请求。我的隔离级别是 READ_COMMITED,效果很好。

public synchronized Schedule getSchedule(Date date) {
  Schedule schedule = dao.getSchedule(date);
  if (schedule == null) {
    schedule = createSchedule(date);
    dao.save(schedule);
    HibernateUtils.getCurrentSession().getTransaction().commit();
    HibernateUtils.getCurrentSession().getTransaction().begin();

  }
  return schedule;
}

现在我在这个项目中使用 Spring,并且使用 aop 进行事务管理。我已删除手动交易代码。我正在使用多个线程进行测试,但我遇到了死锁原因:java.sql.SQLException:超过了锁定等待超时;尝试重启事务

我的交易 AOP:

<tx:advice id="txAdvice">
      <tx:attributes >
      <tx:method name="getSchedule" isolation="SERIALIZABLE" />
      <tx:method name="*" />
      </tx:attributes>
    </tx:advice>
4

1 回答 1

0
@Autowire
private HibernateTransactionManager txManager;

用以下方法包装方法体:

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("transactionName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus ts = txManager.getTransaction(def);

//Body Code

txManager.commit(ts);
于 2013-05-23T18:39:12.183 回答