You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

global_transaction.go 5.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package tm
  18. import (
  19. "context"
  20. "fmt"
  21. "sync"
  22. "github.com/pkg/errors"
  23. "github.com/seata/seata-go/pkg/common/log"
  24. "github.com/seata/seata-go/pkg/protocol/message"
  25. "github.com/seata/seata-go/pkg/remoting/getty"
  26. )
  27. type GlobalTransaction struct {
  28. Xid string
  29. Status message.GlobalStatus
  30. Role GlobalTransactionRole
  31. }
  32. var (
  33. // singletone ResourceManagerFacade
  34. globalTransactionManager *GlobalTransactionManager
  35. onceGlobalTransactionManager = &sync.Once{}
  36. )
  37. func GetGlobalTransactionManager() *GlobalTransactionManager {
  38. if globalTransactionManager == nil {
  39. onceGlobalTransactionManager.Do(func() {
  40. globalTransactionManager = &GlobalTransactionManager{}
  41. })
  42. }
  43. return globalTransactionManager
  44. }
  45. type GlobalTransactionManager struct {
  46. }
  47. // Begin a new global transaction with given timeout and given name.
  48. func (g *GlobalTransactionManager) Begin(ctx context.Context, gtr *GlobalTransaction, timeout int32, name string) error {
  49. if gtr.Role != LAUNCHER {
  50. log.Infof("Ignore GlobalStatusBegin(): just involved in global transaction %s", gtr.Xid)
  51. return nil
  52. }
  53. if gtr.Xid != "" {
  54. return errors.New(fmt.Sprintf("Global transaction already exists,can't begin a new global transaction, currentXid = %s ", gtr.Xid))
  55. }
  56. req := message.GlobalBeginRequest{
  57. TransactionName: name,
  58. Timeout: timeout,
  59. }
  60. res, err := getty.GetGettyRemotingClient().SendSyncRequest(req)
  61. if err != nil {
  62. log.Errorf("GlobalBeginRequest error, xid %s, error %v", gtr.Xid, err)
  63. return err
  64. }
  65. if res == nil || res.(message.GlobalBeginResponse).ResultCode == message.ResultCodeFailed {
  66. log.Errorf("GlobalBeginRequest error, xid %s, res %v", gtr.Xid, res)
  67. return err
  68. }
  69. log.Infof("GlobalBeginRequest success, xid %s, res %v", gtr.Xid, res)
  70. gtr.Status = message.GlobalStatusBegin
  71. gtr.Xid = res.(message.GlobalBeginResponse).Xid
  72. SetXID(ctx, res.(message.GlobalBeginResponse).Xid)
  73. return nil
  74. }
  75. // Commit the global transaction.
  76. func (g *GlobalTransactionManager) Commit(ctx context.Context, gtr *GlobalTransaction) error {
  77. if gtr.Role != LAUNCHER {
  78. log.Infof("Ignore Commit(): just involved in global gtr [{}]", gtr.Xid)
  79. return nil
  80. }
  81. if gtr.Xid == "" {
  82. return errors.New("Commit xid should not be empty")
  83. }
  84. // todo: replace retry with config
  85. var (
  86. err error
  87. res interface{}
  88. )
  89. for retry := 5; retry > 0; retry-- {
  90. req := message.GlobalCommitRequest{
  91. AbstractGlobalEndRequest: message.AbstractGlobalEndRequest{
  92. Xid: gtr.Xid,
  93. },
  94. }
  95. res, err = getty.GetGettyRemotingClient().SendSyncRequest(req)
  96. if err != nil {
  97. log.Errorf("GlobalCommitRequest error, xid %s, error %v", gtr.Xid, err)
  98. } else {
  99. break
  100. }
  101. }
  102. if err == nil && res != nil {
  103. gtr.Status = res.(message.GlobalCommitResponse).GlobalStatus
  104. }
  105. UnbindXid(ctx)
  106. log.Infof("GlobalCommitRequest commit success, xid %s", gtr.Xid)
  107. return err
  108. }
  109. // Rollback the global transaction.
  110. func (g *GlobalTransactionManager) Rollback(ctx context.Context, gtr *GlobalTransaction) error {
  111. if gtr.Role != LAUNCHER {
  112. log.Infof("Ignore Commit(): just involved in global gtr [{}]", gtr.Xid)
  113. return nil
  114. }
  115. if gtr.Xid == "" {
  116. return errors.New("Commit xid should not be empty")
  117. }
  118. // todo: replace retry with config
  119. var (
  120. err error
  121. res interface{}
  122. )
  123. for retry := 5; retry > 0; retry-- {
  124. req := message.GlobalRollbackRequest{
  125. AbstractGlobalEndRequest: message.AbstractGlobalEndRequest{
  126. Xid: gtr.Xid,
  127. },
  128. }
  129. res, err = getty.GetGettyRemotingClient().SendSyncRequest(req)
  130. if err != nil {
  131. log.Errorf("GlobalRollbackRequest error, xid %s, error %v", gtr.Xid, err)
  132. } else {
  133. break
  134. }
  135. }
  136. if err == nil && res != nil {
  137. gtr.Status = res.(message.GlobalRollbackResponse).GlobalStatus
  138. }
  139. UnbindXid(ctx)
  140. return err
  141. }
  142. // Suspend the global transaction.
  143. func (g *GlobalTransactionManager) Suspend() (SuspendedResourcesHolder, error) {
  144. panic("implement me")
  145. }
  146. // Resume the global transaction.
  147. func (g *GlobalTransactionManager) Resume(suspendedResourcesHolder SuspendedResourcesHolder) error {
  148. panic("implement me")
  149. }
  150. // report the global transaction status.
  151. func (g *GlobalTransactionManager) GlobalReport(globalStatus message.GlobalStatus) error {
  152. panic("implement me")
  153. }