15

我的 application.properties 文件中有一些配置:

...
quarkus.datasource.url=jdbc:postgresql://...:5432/....
quarkus.datasource.driver=org.postgresql.Driver
quarkus.datasource.username=user
quarkus.datasource.password=password
quarkus.hibernate-orm.database.generation=update
...

我有一个带有 @Transactional 方法的调度程序,它需要很长时间才能完成执行:

@ApplicationScoped
class MyScheduler {

...

    @Transactional
    @Scheduled(every = "7200s")
    open fun process() {

        ... my slow proccess goes here...
        entityManager.persist(myObject)

    }
}

然后,事务方法收到一个超时错误,如下所示:

2019-06-24 20:11:59,874 WARN  [com.arj.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffff0a000020:d58d:5cdad26e:81 in state  RUN

2019-06-24 20:12:47,198 WARN  [com.arj.ats.arjuna] (DefaultQuartzScheduler_Worker-3) ARJUNA012077: Abort called on already aborted atomic action 0:ffff0a000020:d58d:5cdad26e:81

Caused by: javax.transaction.RollbackException: ARJUNA016102: The transaction is not active! Uid is 0:ffff0a000020:d58d:5cdad26e:81

我相信我必须增加我的事务方法的超时时间。但我不知道我该怎么做。

有人可以帮助我吗?

谢谢!

4

4 回答 4

10

似乎这已经改变了 -> 现在可以设置事务超时:

https://quarkus.io/guides/transaction

您可以通过以下属性配置默认事务超时,即适用于事务管理器管理的所有事务的超时:

quarkus.transaction-manager.default-transaction-timeout = 240s

-> 指定为持续时间(java.time.Duration 格式)。默认为 60 秒

于 2021-02-18T16:47:38.263 回答
7

Quarkus 还不允许您全局配置默认事务超时(请参阅https://github.com/quarkusio/quarkus/pull/2984)。

但是您应该能够在用户事务级别执行此操作。

您可以注入 UserTransaction 对象并在 postconstruct 块中设置事务超时。

像这样的东西应该工作:

@ApplicationScoped
class MyScheduler {

    @Inject UserTransaction userTransaction;

    @PostConstruct
    fun init() {
        //set a timeout as high as you need
        userTransaction.setTransactionTimeout(3600);
    }

    @Transactional
    @Scheduled(every = "7200s")
    open fun process() {
        entityManager.persist(myObject)

    }
}

如果您提取在 Service 中进行事务的代码,则可以使用带有 @Transactional 注释的服务,在调度程序中注入 UserTransaction 并在调用服务之前设置事务超时。

所有这些都有效,我刚刚测试了这两种解决方案;)

于 2019-06-25T09:33:52.303 回答
3

感谢@loicmathieu 的回答!

我将在下面附加一些更多细节。

您需要在开始事务之前删除 @Transactional 并设置事务超时。最后,您必须提交事务:

import io.quarkus.scheduler.Scheduled
import javax.enterprise.context.ApplicationScoped
import javax.inject.Inject
import javax.transaction.UserTransaction

@ApplicationScoped
open class MyScheduler {

    @Inject
    lateinit var em: EntityManager

    @Inject
    lateinit var ut: UserTransaction

    @Scheduled(every = "3600s")
    open fun process() {

        ut.setTransactionTimeout(3600)
        ut.begin()
        offerService.processOffers()
        ut.commit()
    }
}
于 2019-06-26T14:13:47.907 回答
1

使用 @TransactionConfiguration 注释并指定秒数:

@Transactional
@TransactionConfiguration(timeout = 9876)
@Scheduled(every = "7200s")
open fun process() {

    ... my slow proccess goes here...
    entityManager.persist(myObject)

}
于 2021-06-23T07:48:40.487 回答