2017-01-03 11:20:28 +03:00
// Copyright 2016 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package xorm
// Begin a transaction
func ( session * Session ) Begin ( ) error {
2017-08-22 14:39:52 +03:00
if session . isAutoCommit {
2019-06-23 18:22:43 +03:00
tx , err := session . DB ( ) . BeginTx ( session . ctx , nil )
2017-01-03 11:20:28 +03:00
if err != nil {
return err
}
2017-08-22 14:39:52 +03:00
session . isAutoCommit = false
session . isCommitedOrRollbacked = false
session . tx = tx
2017-01-03 11:20:28 +03:00
session . saveLastSQL ( "BEGIN TRANSACTION" )
}
return nil
}
// Rollback When using transaction, you can rollback if any error
func ( session * Session ) Rollback ( ) error {
2017-08-22 14:39:52 +03:00
if ! session . isAutoCommit && ! session . isCommitedOrRollbacked {
session . saveLastSQL ( session . engine . dialect . RollBackStr ( ) )
session . isCommitedOrRollbacked = true
2018-07-20 05:10:17 +03:00
session . isAutoCommit = true
2017-08-22 14:39:52 +03:00
return session . tx . Rollback ( )
2017-01-03 11:20:28 +03:00
}
return nil
}
// Commit When using transaction, Commit will commit all operations.
func ( session * Session ) Commit ( ) error {
2017-08-22 14:39:52 +03:00
if ! session . isAutoCommit && ! session . isCommitedOrRollbacked {
2017-01-03 11:20:28 +03:00
session . saveLastSQL ( "COMMIT" )
2017-08-22 14:39:52 +03:00
session . isCommitedOrRollbacked = true
2018-07-20 05:10:17 +03:00
session . isAutoCommit = true
2017-01-03 11:20:28 +03:00
var err error
2017-08-22 14:39:52 +03:00
if err = session . tx . Commit ( ) ; err == nil {
2017-01-03 11:20:28 +03:00
// handle processors after tx committed
closureCallFunc := func ( closuresPtr * [ ] func ( interface { } ) , bean interface { } ) {
if closuresPtr != nil {
for _ , closure := range * closuresPtr {
closure ( bean )
}
}
}
for bean , closuresPtr := range session . afterInsertBeans {
closureCallFunc ( closuresPtr , bean )
if processor , ok := interface { } ( bean ) . ( AfterInsertProcessor ) ; ok {
processor . AfterInsert ( )
}
}
for bean , closuresPtr := range session . afterUpdateBeans {
closureCallFunc ( closuresPtr , bean )
if processor , ok := interface { } ( bean ) . ( AfterUpdateProcessor ) ; ok {
processor . AfterUpdate ( )
}
}
for bean , closuresPtr := range session . afterDeleteBeans {
closureCallFunc ( closuresPtr , bean )
if processor , ok := interface { } ( bean ) . ( AfterDeleteProcessor ) ; ok {
processor . AfterDelete ( )
}
}
cleanUpFunc := func ( slices * map [ interface { } ] * [ ] func ( interface { } ) ) {
if len ( * slices ) > 0 {
* slices = make ( map [ interface { } ] * [ ] func ( interface { } ) , 0 )
}
}
cleanUpFunc ( & session . afterInsertBeans )
cleanUpFunc ( & session . afterUpdateBeans )
cleanUpFunc ( & session . afterDeleteBeans )
}
return err
}
return nil
}