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.

session_tx.go 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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("ROLL BACK")
  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. if err := session.tx.Commit(); err != nil {
  36. return err
  37. }
  38. // handle processors after tx committed
  39. closureCallFunc := func(closuresPtr *[]func(interface{}), bean interface{}) {
  40. if closuresPtr != nil {
  41. for _, closure := range *closuresPtr {
  42. closure(bean)
  43. }
  44. }
  45. }
  46. for bean, closuresPtr := range session.afterInsertBeans {
  47. closureCallFunc(closuresPtr, bean)
  48. if processor, ok := interface{}(bean).(AfterInsertProcessor); ok {
  49. processor.AfterInsert()
  50. }
  51. }
  52. for bean, closuresPtr := range session.afterUpdateBeans {
  53. closureCallFunc(closuresPtr, bean)
  54. if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
  55. processor.AfterUpdate()
  56. }
  57. }
  58. for bean, closuresPtr := range session.afterDeleteBeans {
  59. closureCallFunc(closuresPtr, bean)
  60. if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok {
  61. processor.AfterDelete()
  62. }
  63. }
  64. cleanUpFunc := func(slices *map[interface{}]*[]func(interface{})) {
  65. if len(*slices) > 0 {
  66. *slices = make(map[interface{}]*[]func(interface{}), 0)
  67. }
  68. }
  69. cleanUpFunc(&session.afterInsertBeans)
  70. cleanUpFunc(&session.afterUpdateBeans)
  71. cleanUpFunc(&session.afterDeleteBeans)
  72. }
  73. return nil
  74. }
  75. // IsInTx if current session is in a transaction
  76. func (session *Session) IsInTx() bool {
  77. return !session.isAutoCommit
  78. }