session_tx.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2016 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. // Begin a transaction
  6. func (session *Session) Begin() error {
  7. if session.IsAutoCommit {
  8. tx, err := session.DB().Begin()
  9. if err != nil {
  10. return err
  11. }
  12. session.IsAutoCommit = false
  13. session.IsCommitedOrRollbacked = false
  14. session.Tx = tx
  15. session.saveLastSQL("BEGIN TRANSACTION")
  16. }
  17. return nil
  18. }
  19. // Rollback When using transaction, you can rollback if any error
  20. func (session *Session) Rollback() error {
  21. if !session.IsAutoCommit && !session.IsCommitedOrRollbacked {
  22. session.saveLastSQL(session.Engine.dialect.RollBackStr())
  23. session.IsCommitedOrRollbacked = true
  24. return session.Tx.Rollback()
  25. }
  26. return nil
  27. }
  28. // Commit When using transaction, Commit will commit all operations.
  29. func (session *Session) Commit() error {
  30. if !session.IsAutoCommit && !session.IsCommitedOrRollbacked {
  31. session.saveLastSQL("COMMIT")
  32. session.IsCommitedOrRollbacked = true
  33. var err error
  34. if err = session.Tx.Commit(); err == nil {
  35. // handle processors after tx committed
  36. closureCallFunc := func(closuresPtr *[]func(interface{}), bean interface{}) {
  37. if closuresPtr != nil {
  38. for _, closure := range *closuresPtr {
  39. closure(bean)
  40. }
  41. }
  42. }
  43. for bean, closuresPtr := range session.afterInsertBeans {
  44. closureCallFunc(closuresPtr, bean)
  45. if processor, ok := interface{}(bean).(AfterInsertProcessor); ok {
  46. processor.AfterInsert()
  47. }
  48. }
  49. for bean, closuresPtr := range session.afterUpdateBeans {
  50. closureCallFunc(closuresPtr, bean)
  51. if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
  52. processor.AfterUpdate()
  53. }
  54. }
  55. for bean, closuresPtr := range session.afterDeleteBeans {
  56. closureCallFunc(closuresPtr, bean)
  57. if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok {
  58. processor.AfterDelete()
  59. }
  60. }
  61. cleanUpFunc := func(slices *map[interface{}]*[]func(interface{})) {
  62. if len(*slices) > 0 {
  63. *slices = make(map[interface{}]*[]func(interface{}), 0)
  64. }
  65. }
  66. cleanUpFunc(&session.afterInsertBeans)
  67. cleanUpFunc(&session.afterUpdateBeans)
  68. cleanUpFunc(&session.afterDeleteBeans)
  69. }
  70. return err
  71. }
  72. return nil
  73. }