[英]How to know if a transactional method in a grails service was successful?
[英]grails how to disable transactional for a method
我有一种服务方法来转移资金到外部系统。
它应该首先在我们的系统中创建一个事务(所以我们有一个transactionId)然后我们调用外部系统。 如果外部系统出现故障,我们需要回滚事务,然后在我们的付款审核日志表中写入新记录,无论呼叫是否失败或有效。
在这种情况下,我无法弄清楚如何控制交易。
我理解默认情况下服务是事务性的。
我假设我可以创建3个方法(它们现在都是1个方法,这不起作用,因为我无法控制提交的内容和回滚的内容)
如果1失败,我需要回滚1,并且不做任何其他事情。 如果2失败,我需要回滚1,但是写3.如果1和2工作,我需要写3。
我不知道如何注释这些,或如何构建第4个请求来管理3。
我会用这样的东西:
package com.myapp
import grails.transaction.Transactional
import org.springframework.transaction.annotation.Propagation
@Transactional
class MyService {
def createPaymentTransaction() {}
def sendToPaymentSystem() {}
@Transactional(propagation=Propagation.REQUIRES_NEW)
def createPaymentRecord() {}
def method4() {
try {
def transactionId = createPaymentTransaction()
sendToPaymentSystem(transactionId)
}
finally {
createPaymentRecord()
}
}
}
通过在类级别进行注释,我们为所有方法设置默认值,但可以根据需要进行自定义,例如createPaymentMethod
。
那么将会发生的是调用method4
将加入现有事务,或者在必要时启动一个新事务。 如果在createPaymentTransaction
或sendToPaymentSystem
出现问题,那么事务将被回滚,但是对createPaymentRecord
的调用将发生,因为它位于finally
块中,并且它将在单独的事务中运行,因此它不会受到回滚的影响。主要交易和失败不会影响主要交易。
如果您无法使用新的grails.transaction.Transactional
注释,请使用标准的Spring org.springframework.transaction.annotation.Transactional
注释,但您需要进行一些小的更改。 Grails注释的一个动机是提供与Spring注释相同的功能,但避免在服务中调用带注释的方法的问题。 Spring注释在运行时触发创建代理,该代理拦截所有调用,管理方法的事务性,然后调用服务实例中的实际方法。 但是使用当前代码,对createPaymentRecord
的调用将绕过代理(服务实例只是调用自身),并且不会有新的事务。 Grails注释重写字节码以将每个方法包装在事务模板中,该模板使用适用的注释设置(显式或从类范围注释推断),因此它在内部和外部都能正常工作。 如果使用Spring注释,则需要在代理上调用该方法,该方法只涉及访问此服务的Spring bean。 为GrailsApplication
添加依赖注入作为字段:
def grailsApplication
然后通过调用createPaymentRecord
grailsApplication.mainContext.myService.createPaymentRecord()
在finally
块中。
默认情况下,服务中的所有方法都是事务性的,但您可以使用注释逐个方法地更改行为,例如
import grails.transaction.*
// By default all methods are transactional
@Transactional
class MyService {
@NotTransactional
def notTransactional() {
}
// inherits the class-level default
def transactional() {
}
}
有关事务注释的更多详细信息,请参阅Grails手册 。
如果您需要以比每个方法更精细的级别管理事务,则可以使用withTransaction域类方法以编程方式管理事务 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.