Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.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时手动取消JPA或Hibernate事务_Java_Spring_Hibernate_Jpa_Transactions - Fatal编程技术网

Java 如何在使用Spring时手动取消JPA或Hibernate事务

Java 如何在使用Spring时手动取消JPA或Hibernate事务,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,我正在使用JPA2Hibernate实现和SpringMVC来管理事务 我使用通用DAO模式来管理数据库操作 目前,我们有一个单一方法的事务,类似于: someDao.save (someObject) 它是一个从JSF页面调用的@Transactional方法 save方法是从泛型DAO继承而来的,它持续存在于具有级联oneToMany关系的多个实体的数据库中,但它必须在数据库中执行大约1000条insert语句,因此需要很长的时间 我想为用户提供一种取消操作的方法,但到目前为止,我无法做到

我正在使用JPA2Hibernate实现和SpringMVC来管理事务

我使用通用DAO模式来管理数据库操作

目前,我们有一个单一方法的事务,类似于:

someDao.save (someObject)
它是一个从JSF页面调用的
@Transactional
方法

save方法是从泛型DAO继承而来的,它持续存在于具有级联oneToMany关系的多个实体的数据库中,但它必须在数据库中执行大约1000条insert语句,因此需要很长的时间

我想为用户提供一种取消操作的方法,但到目前为止,我无法做到这一点,当我调用save()方法时,在执行所有插入之前无法取消该方法

我试图抛出一些异常,从注入的PersistenceContext回滚事务,但这没有用,它只是在没有错误的情况下完成:(

显然,我不能从方法中抛出异常,它只是来自我的源代码的一个调用


有没有办法取消操作并强制其回滚?

也许这会对您有所帮助:

HibernateSession提供了一个取消查询-方法,可用于取消当前查询。

注意:在查询真正终止之前,可能需要一些时间。

保存1000个实体不会花费那么长时间。请确保您从以下方面受益:

  • 您需要使用非标识的实体标识符。标识禁用批处理。序列和表生成器允许批处理
  • 设置以下休眠属性:

    <property name="hibernate.order_updates" value="true"/>
    <property name="hibernate.order_inserts" value="true"/>
    <property name="hibernate.jdbc.batch_versioned_data" value="true"/>
    <property name="hibernate.jdbc.fetch_size" value="50"/>
    <property name="hibernate.jdbc.batch_size" value="520"/>
    
    
    
  • 如果要使保存操作超时,则需要使用以下内容对服务方法进行注释:

    • 春天

    • 用于JavaEE

  • 这样,30秒后,您的保存事务将超时,并引发异常,回滚所有插入


    批处理 如果要取消批插入操作,同时允许已处理的项目继续,则需要选择批处理

    您需要将所有项目拆分为块,并将它们分批插入。为此,我将从实际的批处理线程中拆分批处理开始和批处理结束边界。因此,当批处理开始和批处理结束由web请求触发时,批处理由专用线程运行

    这样,您可以:

    • 同时处理批
    • 使用,立即停止所有批处理
    因为查询执行是I/O阻塞操作,所以您需要支持线程中断,因此当批处理结束线程中断批处理执行器时,可以通知您停止处理下一批并尽快退出


    我会使用一个单独的ExecutionService

    谢谢,我会试试这个,尽管我认为如果我的系统被多个用户使用,我可能会终止其他人的交易,我错了吗?thx@MakhzHibernatSession#cancelQuery方法是按会话分配的,一般来说,会话是按JTA事务或线程分配的,因此除非你有一些其他不寻常的配置,它不会杀死其他人的事务。谢谢,好吧,我说了一些1000个实体,不知道有多少,但在我做的测试中,它可能是25000个左右,我们期望更多,这取决于数据,这需要一些时间,而且,我不想自动杀死事务,而是手动,按下“取消”按钮或类似的按钮,但到目前为止我无法这样做。我用批处理设计方案更新了我的响应。为了避免这个Spring+Hibernate错误,您必须在超时时间上再增加1秒,即,如果您想要2秒的超时时间,请将超时时间设置为3: