我正在解析我的应用程序中的xml文件,我正在努力设计这个。
我允许上传我们的xml架构的“不完整”树,这意味着只要树形成良好,它就可以是根节点的任何子子节点。大多数节点都有子节点,只包含一些文本(属性),但我的小xml结构示例中没有包含任何这些节点。
<root>
<childFoo>
<childBar>
</childBar>
</childFoo>
</root>
允许任何一个节点。 现在,我设计了一个XmlInputService,它具有解析各个节点的方法。我只是在控制器中检测到它是什么类型的节点,并相应地将其交给服务方法。
因此,为了保持我的代码干爽和好,我在更高级别重用我的方法。如果我将Root类型的文档传递给服务,它将解析root中直接属于root的任何字段,并将子节点(表示我的域类结构中的子节点)传递给适当的解析方法。服务。
现在,如果用户上传包含约束违规的xml,即具有非唯一名称的元素等,我显然想要回滚它。
让我说我调用parseRoot()并向下调用parseChildFoo()。
在那里我为那里的每个Bar孩子调用parseChildBar()。如果其中一个Bar子项由于约束或其他原因无法验证,我显然希望将事务的回滚级联到parseFoo()。
我将如何实现这一目标?
答案 0 :(得分:1)
对域对象制定这些有效性规则验证约束。
当save()违反约束时,抛出异常并在顶层解析级别捕获它,然后回滚整个事务。 喜欢:
meServiceMethod() {
...
FooDomainClass.withTransaction { status ->
try {
parseRoot(xml)
}
catch (FooBarParentException e) {
status.setRollbackOnly()
// whatever error diagnostics
}
}
...
}
或者你可以简单地让异常飞出服务方法到控制器 - 默认情况下服务方法是事务性的。
答案 1 :(得分:1)
如果你有一个grails服务,它有一个负责解析的方法,你应该抛出一个从你的服务扩展java.lang.RuntimeException的异常,这样就可以告诉用户他们需要修改他们的xml。因此,您的控制器将捕获该异常并为用户提供有意义的错误消息
每当从服务方法抛出runtimeexception时,Grails / Spring都会自动完成所有数据库修改的回滚。
我在Victor的回答中描述的方法的优点是,您不必编写任何代码来让事务在发生故障时回滚。 Grails会为你做的。 IMO,在服务方法中使用withTransaction
闭包没有任何意义。