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().BeginTx(session.ctx, nil)
  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. session.isAutoCommit = true
  25. return session.tx.Rollback()
  26. }
  27. return nil
  28. }
  29. // Commit When using transaction, Commit will commit all operations.
  30. func (session *Session) Commit() error {
  31. if !session.isAutoCommit && !session.isCommitedOrRollbacked {
  32. session.saveLastSQL("COMMIT")
  33. session.isCommitedOrRollbacked = true
  34. session.isAutoCommit = true
  35. var err error
  36. if err = session.tx.Commit(); err == nil {
  37. // handle processors after tx committed
  38. closureCallFunc := func(closuresPtr *[]func(interface{}), bean interface{}) {
  39. if closuresPtr != nil {
  40. for _, closure := range *closuresPtr {
  41. closure(bean)
  42. }
  43. }
  44. }
  45. for bean, closuresPtr := range session.afterInsertBeans {
  46. closureCallFunc(closuresPtr, bean)
  47. if processor, ok := interface{}(bean).(AfterInsertProcessor); ok {
  48. processor.AfterInsert()
  49. }
  50. }
  51. for bean, closuresPtr := range session.afterUpdateBeans {
  52. closureCallFunc(closuresPtr, bean)
  53. if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
  54. processor.AfterUpdate()
  55. }
  56. }
  57. for bean, closuresPtr := range session.afterDeleteBeans {
  58. closureCallFunc(closuresPtr, bean)
  59. if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok {
  60. processor.AfterDelete()
  61. }
  62. }
  63. cleanUpFunc := func(slices *map[interface{}]*[]func(interface{})) {
  64. if len(*slices) > 0 {
  65. *slices = make(map[interface{}]*[]func(interface{}), 0)
  66. }
  67. }
  68. cleanUpFunc(&session.afterInsertBeans)
  69. cleanUpFunc(&session.afterUpdateBeans)
  70. cleanUpFunc(&session.afterDeleteBeans)
  71. }
  72. return err
  73. }
  74. return nil
  75. }