요약 부모는 많은 자식을 가질 수 있습니다. 부모를 추가 한 후에 자식을 추가 할 때 오류가 발생하면 전체 트랜잭션이 롤백되도록 서비스를 작성합니다. 예를 들어, 부모 p1을 추가하고 자식 c1을 성공적으로 추가 한 다음 자식 c2를 추가 할 때 오류가 발생하면 p1과 c1을 모두 롤백해야합니다.Grails에서 트랜잭션을 수행하는 방법
자세한 문제 다음 코드에서
는, 아이의 이름 속성에 고유 제한 조건이있다. 따라서 동일한 이름을 다른 부모와 함께 두 번 추가하려고하면 하위 레코드를 추가하지 말고 상위 레코드를 롤백해야합니다.
제 문제는 상위 레코드가 롤백되지 않는 것입니다.
Grails 1.2-M2 및 Tomcat 6.018과 함께 MySQL을 사용하고 있습니다.
데이터 소스
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
dataSource {
configClass = GrailsAnnotationConfiguration.class
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQLInnoDBDialect
zeroDateTimeBehavior="convertToNull" //Java can't convert ''0000-00-00 00:00:00' to TIMESTAMP
username = "root"
password = "12345"
loggingSql=false
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:mysql://localhost:3306/transtest?zeroDateTimeBehavior=convertToNull"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/transtest?zeroDateTimeBehavior=convertToNull"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/transtest?zeroDateTimeBehavior=convertToNull"
}
}
}
나는 다음과 같은 간단한 도메인 클래스가 있습니다
부모 :
class Parent {
static hasMany = [ children : Child ]
String name
static constraints = {
name(blank:false,unique:true)
}
}
아이를
class Child {
static belongsTo = Parent
String name
Parent parent
static constraints = {
name(blank:false,unique:true)
}
}
간단한 데이터 입력 GSP
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Sample title</title>
</head>
<body>
<h1>Add A Record</h1>
<g:form action="add" name="doAdd">
<table>
<tr>
<td>
Parent Name
</td>
<td>
Child Name
</td>
</tr>
<tr>
<td>
<g:textField name="parentName" />
</td>
<td>
<g:textField name="childName" />
</td>
</tr>
<tr><td><g:submitButton name="update" value="Update" /></td></tr>
</table>
</g:form>
</body>
</html>
컨트롤러
class AddrecordController {
def addRecordsService
def index = {
redirect action:"show", params:params
}
def add = {
println "do add"
addRecordsService.addAll(params)
redirect action:"show", params:params
}
def show = {}
}
서비스
class AddRecordsService {
// boolean transactional = true //shouldn't this be all I need?
static transactional = true // this should work but still doesn't nor does it work if the line is left out completely
def addAll(params) {
println "add all"
println params
def Parent theParent = addParent(params.parentName)
def Child theChild = addChild(params.childName,theParent)
println theParent
println theChild
}
def addParent(pName) {
println "add parent: ${pName}"
def theParent = new Parent(name:pName)
theParent.save()
return theParent
}
def addChild(cName,Parent theParent) {
println "add child: ${cName}"
def theChild = new Child(name:cName,parent:theParent)
theChild.save()
return theChild
}
}
그 중요한 세부 사항을 추가해 주셔서 감사합니다. –
> 또한 > 트랜잭션이 자동으로 롤백되도록하려면 > 서비스 내에 RuntimeException이 throw되는지 확인해야합니다. 그건 내 문제 였어! 관례 적으로 grails가 이렇게해야 할 것처럼 보입니다. –
유효성 검사가 실패 할 경우 null을 반환하는 대신 save() 예외를 throw하도록 구성 옵션이 있다고 생각합니다. – leebutts