데이터베이스/sql 및 드라이버 패키지와 Tx를 사용하면 다른 트랜잭션을 시도하지 않고 트랜잭션이 커밋되거나 롤백되었는지 여부를 감지하는 것처럼 보이지 않습니다. 결과를 확인한 다음 오류를 검사하여 오류 유형을 판별하십시오. 나는 Tx 객체에서 커밋 여부를 결정할 수 있기를 원합니다. 물론, Tx를 사용하는 함수에서 다른 변수를 정의하고 설정할 수는 있지만 꽤 많은 수의 변수가 있으며 매번 2 번 (변수와 대입)입니다. 또한 필요한 경우 롤백을 수행하는 지연된 함수가 있으며 bool 변수를 전달해야합니다.
커밋 또는 롤백 후에 Tx 변수를 nil로 설정하면 받아 들일 수 있습니까? GC가 메모리를 복구합니까, 아니면 아니오입니까? 아니면 더 좋은 대안이 있습니까?데이터베이스/SQL Tx - 커밋 또는 롤백 감지
답변
왜이 작업을 수행해야합니까? Begin()
을 호출하는 함수는 Commit()
또는 Rollback()
을 호출하고 적절한 오류를 반환해야합니다. 내가 커밋 또는 롤백해야하는지 여부를 확인 error
을 확인하고 있습니다 방법
func (s Service) DoSomething() (err error) {
tx, err := s.db.Begin()
if err != nil {
return
}
defer func() {
if err != nil {
tx.Rollback()
return
}
err = tx.Commit()
}()
if _, err = tx.Exec(...); err != nil {
return
}
if _, err = tx.Exec(...); err != nil {
return
}
// ...
return
}
공지 사항 :
예를 들어,이 코드는 커밋 또는 롤백 오류가 반환 여부에 따라 않습니다. 그러나 위의 예제는 패닉을 처리하지 않습니다.
나는 모든 데이터베이스 루틴에서 커밋/롤백 로직을 사용하지 않기 때문에 대개 트랜잭션 처리기에서 래핑합니다. 이의 라인을 따라 뭔가 :이 저 대신이 작업을 수행 할 수 있습니다
func Transact(db *sql.DB, txFunc func(*sql.Tx) error) (err error) {
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p) // re-throw panic after Rollback
} else if err != nil {
tx.Rollback()
} else {
err = tx.Commit()
}
}()
err = txFunc(tx)
return err
}
: 내 트랜잭션 내에서 아무것도 패닉 경우 자동으로 트랜잭션 처리기에 의해 처리 있다고
func (s Service) DoSomething() error {
return Transact(s.db, func (tx *sql.Tx) error {
if _, err := tx.Exec(...); err != nil {
return err
}
if _, err := tx.Exec(...); err != nil {
return err
}
})
}
알 수 있습니다.
현실적인 구현에서는 Commit()
또는 Rollback()
으로 원하지 않는 호출을 방지하기 위해 * sql.Tx 대신 인터페이스를 전달합니다.
여기 설명하는 간단한 코드 조각 얼마나 defer
작업 (인쇄 4가 아닌 5) :
package main
func test() (i int) {
defer func() {
i = 4
}()
return 5
}
func main() {
println(test())
}
좋은 답변입니다! 나는 두 번째 doSomething() 구현이 끝날 무렵에 "return nil"을 놓쳤다 고 생각한다. – splinter123
루크, 언제 어떻게 평가 되나요? 문서에 따라 "오류"는 지연 호출에서 처음 선언 될 때 값을 가져야합니다.그래서 이것은 실제로 나에게 다소 혼란 스럽습니다. 연기에 사용 된 "오류"의 값이 바뀌었기 때문입니다. – mirage
지연은 다음과 같이 연기하기 전에 선언됩니다. = (콜론은 같음). anon func이 캡처합니다. Defer는 값이 반환되기 직전에 호출됩니다. 그것은 그것을 설정할 수 있습니다. 패닉이 발생하면 오류가 복구되어 반환됩니다. 오류가 어떤 식 으로든 발생하면 롤백이 발생합니다. 마지막으로 커밋은 에러가없고 err (현재는 nil)이 에러로 인해 리턴 값을 커밋하도록 설정되면 발생합니다. – Luke
- 1. 그냥 SELECT 명령으로 트랜잭션 롤백 또는 커밋
- 2. .GIT의 롤백 커밋
- 3. savepoint mysql에서 롤백 커밋
- 4. 커밋 된 데이터 롤백
- 5. 레일에서 커밋 후 롤백 트랜잭션
- 6. MySQL 커밋 및 롤백 실패
- 7. 두 커밋 전에서 힘내 롤백
- 8. ZF2 MySQL 롤백 커밋 기능
- 9. PostgreSQL에서 커밋, 세이브 포인트, 롤백?
- 10. 커밋 또는 롤백 할 사용자 정의 컨트롤이있는 JSF2 + EJB3 + CRUD?
- 11. 지도에 저장 (또는 커밋) 및 롤백 메소드를 구현합니다.
- 12. 커밋 또는 롤백 할 트랜잭션에 액세스하는 기본 방법은 무엇입니까?
- 13. Camus의 예상 된 커밋/롤백 동작은 무엇입니까?
- 14. Mercurial에서 다중 커밋 (공개하기 전에 푸시) 롤백
- 15. Django models.py 트랜잭션 롤백/커밋 문제
- 16. 스프링 배치의 커밋 간격과 롤백 처리
- 17. 트랜잭션 롤백 및 커밋 SQL Server
- 18. 자식 롤백 변화는 단지 몇 커밋
- 19. PDO 다중 쿼리 : 커밋 및 롤백 트랜잭션
- 20. 트랜잭션 이벤트 (커밋, 롤백)를 얻는 방법
- 21. Gridview에서 롤백 및 커밋 정보 삭제 이벤트
- 22. mysql 트랜잭션 커밋 및 롤백 예제
- 23. 원자 키워드를 사용하여 커밋 및 롤백
- 24. 롤백
- 25. 힘내 상태 롤백 후 커밋 단계 앞으로 이동
- 26. 수행 방법 VB.net을 사용하여 SQL 서버에서 커밋/롤백
- 27. JMS 트랜잭션 세션 : 특정 메시지에 대한 커밋/롤백
- 28. 오류가없는 경우 트랜잭션을 커밋, Oracle SQL *에서 오류가 발생하면 롤백
- 29. SQL 롤백 다중 저장 프로 시저 삽입에서 커밋
- 30. 데몬 또는 서비스 커밋
내가 문제를 이해한다면 확실하지. 커밋 또는 롤백 중 하나를 사용하여 트랜잭션을 종료해야하므로 수행 한 작업을 알 수 있지만 추가 변수에서이 작업을 기억하고 싶지는 않습니다. Tx와 bool을 자신의 RememberingTx로 래핑 할 수 있습니다. 이렇게하면 행 수가 약간 줄어 듭니다. GC 질문에 관하여 : 당신이 nil 또는 not로 설정하면 그것은 중요하지 않습니다 : 메모리가 남아 있지 않으면 메모리는 회수 될 것입니다. 그래서 : 네,'var tx * Tx; 한조각; if cond {tx.Commit; tx = nil} else {tx.Rollback}; 한조각; tx == nil {커밋 된 경우} else {롤백 된} '하지만 추한 느낌. – Volker
그게 무슨 일인가지만, Tx가 nil이 아니면 롤백을 수행하는 지연된 func이 있습니다. 트랜잭션이 커밋되면 Tx를 사용할 수 없기 때문에 Tx를 nil로 설정할 계획입니다. 그러나 롤백을 시도하고 오류 메시지를 테스트하는 것은 그리 좋지 않습니다. 문제는 AFAIK가 트랜잭션이 Tx에서 "완료"되었는지 테스트 할 수있는 방법이 없다는 것입니다. 왜 그런 식으로했는지, 아마도 퍼포먼스인지 모르겠습니다. –