Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle https://xorm.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

128 lines
3.1 KiB

  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. import (
  6. "time"
  7. "xorm.io/xorm/log"
  8. )
  9. // Begin a transaction
  10. func (session *Session) Begin() error {
  11. if session.isAutoCommit {
  12. tx, err := session.DB().BeginTx(session.ctx, nil)
  13. if err != nil {
  14. return err
  15. }
  16. session.isAutoCommit = false
  17. session.isCommitedOrRollbacked = false
  18. session.tx = tx
  19. session.saveLastSQL("BEGIN TRANSACTION")
  20. }
  21. return nil
  22. }
  23. // Rollback When using transaction, you can rollback if any error
  24. func (session *Session) Rollback() error {
  25. if !session.isAutoCommit && !session.isCommitedOrRollbacked {
  26. session.saveLastSQL("ROLL BACK")
  27. session.isCommitedOrRollbacked = true
  28. session.isAutoCommit = true
  29. start := time.Now()
  30. needSQL := session.DB().NeedLogSQL(session.ctx)
  31. if needSQL {
  32. session.engine.logger.BeforeSQL(log.LogContext{
  33. Ctx: session.ctx,
  34. SQL: "ROLL BACK",
  35. })
  36. }
  37. err := session.tx.Rollback()
  38. if needSQL {
  39. session.engine.logger.AfterSQL(log.LogContext{
  40. Ctx: session.ctx,
  41. SQL: "ROLL BACK",
  42. ExecuteTime: time.Now().Sub(start),
  43. Err: err,
  44. })
  45. }
  46. return err
  47. }
  48. return nil
  49. }
  50. // Commit When using transaction, Commit will commit all operations.
  51. func (session *Session) Commit() error {
  52. if !session.isAutoCommit && !session.isCommitedOrRollbacked {
  53. session.saveLastSQL("COMMIT")
  54. session.isCommitedOrRollbacked = true
  55. session.isAutoCommit = true
  56. start := time.Now()
  57. needSQL := session.DB().NeedLogSQL(session.ctx)
  58. if needSQL {
  59. session.engine.logger.BeforeSQL(log.LogContext{
  60. Ctx: session.ctx,
  61. SQL: "COMMIT",
  62. })
  63. }
  64. err := session.tx.Commit()
  65. if needSQL {
  66. session.engine.logger.AfterSQL(log.LogContext{
  67. Ctx: session.ctx,
  68. SQL: "COMMIT",
  69. ExecuteTime: time.Now().Sub(start),
  70. Err: err,
  71. })
  72. }
  73. if err != nil {
  74. return err
  75. }
  76. // handle processors after tx committed
  77. closureCallFunc := func(closuresPtr *[]func(interface{}), bean interface{}) {
  78. if closuresPtr != nil {
  79. for _, closure := range *closuresPtr {
  80. closure(bean)
  81. }
  82. }
  83. }
  84. for bean, closuresPtr := range session.afterInsertBeans {
  85. closureCallFunc(closuresPtr, bean)
  86. if processor, ok := interface{}(bean).(AfterInsertProcessor); ok {
  87. processor.AfterInsert()
  88. }
  89. }
  90. for bean, closuresPtr := range session.afterUpdateBeans {
  91. closureCallFunc(closuresPtr, bean)
  92. if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
  93. processor.AfterUpdate()
  94. }
  95. }
  96. for bean, closuresPtr := range session.afterDeleteBeans {
  97. closureCallFunc(closuresPtr, bean)
  98. if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok {
  99. processor.AfterDelete()
  100. }
  101. }
  102. cleanUpFunc := func(slices *map[interface{}]*[]func(interface{})) {
  103. if len(*slices) > 0 {
  104. *slices = make(map[interface{}]*[]func(interface{}), 0)
  105. }
  106. }
  107. cleanUpFunc(&session.afterInsertBeans)
  108. cleanUpFunc(&session.afterUpdateBeans)
  109. cleanUpFunc(&session.afterDeleteBeans)
  110. }
  111. return nil
  112. }