Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring/Hibernate/事务同步问题_Java_Spring_Hibernate_Transactions_Deadlock - Fatal编程技术网

Java Spring/Hibernate/事务同步问题

Java Spring/Hibernate/事务同步问题,java,spring,hibernate,transactions,deadlock,Java,Spring,Hibernate,Transactions,Deadlock,我有一个服务,它根据输入:date返回一个持久化的Schedule对象。我有多个线程调用此方法,我希望确保唯一性。我不想捕获约束冲突并给任何用户一个错误。我需要的是:如果一个线程调用该方法,并且该日期不存在Schedule对象,则该线程创建它,其他线程等待。在我使用Spring之前,在我的web应用程序中只需简单地使用Hibernate,我已通过以下方式完成: 我在hibernate中使用了ManagedSessionContext。我在每个web请求的开头启动一个事务,并在最后提交它。对于同步

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

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

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>

将方法体包装为:

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

//Body Code

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

//Body Code

txManager.commit(ts);