pkr*_*ety 0 grails spring transactions spring-transactions
我是春季/学生交易的新手,阅读后我仍然不清楚,所以我在这里发帖,
我有一个服务类,注释为@Transactional,我有一些方法,其中一些注释为
@Transactional(propagation = Propagation.REQUIRES_NEW)
Run Code Online (Sandbox Code Playgroud)
其中一些不是.
@Transactional
class SomeService {
def findJob() {
MyInstance myInstance = getMeAJob();
if (myInstance) {
doSomeThing(myInstance)
doTask()
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception)
private doSomeThing(MyInstance myInst) {
myObj = MyInstance.lock(myInst.id)
try {
differentObj = doTask(myObj)
myObj.save()
doAnotherThing()
}
} catch (Exception e) {
log("Error in doAnotherTask")
}
}
private doAnotherThing(MyInstace myInst) {
perform some update on myInst
myInstant.save(flush: true)
}
private doTask() {
}
Run Code Online (Sandbox Code Playgroud)
将在t2中执行的方法 - doSomeThing() - 在异常情况下不会影响"t1"(回滚)
doAnotherThing()方法将使用哪一个?因为我是从doSomething()调用它的?
如果您有类范围注释,则任何未注释的方法都会使用这些设置,注释方法会使用该注释中的设置覆盖类级别设置.
但请注意,当使用Spring的注释支持(带有@org.springframework.transaction.annotation.Transactional)注释时,仅支持公共方法.不会出现错误,但会自动忽略注释.
但即使你公开doSomeThing(通过删除private关键字隐式地或通过将其更改为显式public),它将无法按照您的预期doSomeThing进行操作findJob.这是因为Spring的注释会在运行时触发创建类的代理.在这种情况下为您的服务注册的Spring bean是一个代理实例,它具有您的类的"真实"实例作为其委托.所有事务公共方法都被代理拦截,它启动/加入/ etc.一个事务,然后调用您的服务方法.一旦你在服务实例中的"代理"下面,所有方法调用都是直接的,任何注释设置都没有效果.要使它工作,您需要在Spring bean上调用该方法并通过代理来启动新事务.
要避免此代理问题,请改用Grails @grails.transaction.Transactional注释.它支持与Spring注释相同的事务功能,但是AST转换不是创建代理,而是重写您的方法以将它们包装在事务中.这使得可以像您一样进行直接方法调用,并创建新事务或在注释属性定义的其他事务语义下运行.
我做了一个谈话而回上可能会提供一些线索Grails的使用事务.
| 归档时间: |
|
| 查看次数: |
535 次 |
| 最近记录: |