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.

undo.go 5.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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 base
  18. import (
  19. "context"
  20. "database/sql"
  21. "database/sql/driver"
  22. "github.com/arana-db/parser/mysql"
  23. "strings"
  24. "github.com/pkg/errors"
  25. "github.com/seata/seata-go/pkg/common/log"
  26. "github.com/seata/seata-go/pkg/common/util"
  27. "github.com/seata/seata-go/pkg/constant"
  28. "github.com/seata/seata-go/pkg/datasource/sql/undo"
  29. "github.com/seata/seata-go/pkg/datasource/sql/types"
  30. )
  31. var _ undo.UndoLogManager = (*BaseUndoLogManager)(nil)
  32. var ErrorDeleteUndoLogParamsFault = errors.New("xid or branch_id can't nil")
  33. // CheckUndoLogTableExistSql check undo log if exist
  34. const CheckUndoLogTableExistSql = "SELECT 1 FROM " + constant.UndoLogTableName + " LIMIT 1"
  35. // BaseUndoLogManager
  36. type BaseUndoLogManager struct{}
  37. // Init
  38. func (m *BaseUndoLogManager) Init() {
  39. }
  40. // InsertUndoLog
  41. func (m *BaseUndoLogManager) InsertUndoLog(l []undo.BranchUndoLog, tx driver.Conn) error {
  42. return nil
  43. }
  44. // DeleteUndoLog exec delete single undo log operate
  45. func (m *BaseUndoLogManager) DeleteUndoLog(ctx context.Context, xid string, branchID int64, conn *sql.Conn) error {
  46. stmt, err := conn.PrepareContext(ctx, constant.DeleteUndoLogSql)
  47. if err != nil {
  48. log.Errorf("[DeleteUndoLog] prepare sql fail, err: %v", err)
  49. return err
  50. }
  51. if _, err = stmt.ExecContext(ctx, branchID, xid); err != nil {
  52. log.Errorf("[DeleteUndoLog] exec delete undo log fail, err: %v", err)
  53. return err
  54. }
  55. return nil
  56. }
  57. // BatchDeleteUndoLog exec delete undo log operate
  58. func (m *BaseUndoLogManager) BatchDeleteUndoLog(xid []string, branchID []int64, conn *sql.Conn) error {
  59. // build delete undo log sql
  60. batchDeleteSql, err := m.getBatchDeleteUndoLogSql(xid, branchID)
  61. if err != nil {
  62. log.Errorf("get undo sql log fail, err: %v", err)
  63. return err
  64. }
  65. ctx := context.Background()
  66. // prepare deal sql
  67. stmt, err := conn.PrepareContext(ctx, batchDeleteSql)
  68. if err != nil {
  69. log.Errorf("prepare sql fail, err: %v", err)
  70. return err
  71. }
  72. branchIDStr, err := util.Int64Slice2Str(branchID, ",")
  73. if err != nil {
  74. log.Errorf("slice to string transfer fail, err: %v", err)
  75. return err
  76. }
  77. // exec sql stmt
  78. if _, err = stmt.ExecContext(ctx, branchIDStr, strings.Join(xid, ",")); err != nil {
  79. log.Errorf("exec delete undo log fail, err: %v", err)
  80. return err
  81. }
  82. return nil
  83. }
  84. // FlushUndoLog
  85. func (m *BaseUndoLogManager) FlushUndoLog(txCtx *types.TransactionContext, tx driver.Conn) error {
  86. return nil
  87. }
  88. // RunUndo
  89. func (m *BaseUndoLogManager) RunUndo(xid string, branchID int64, conn *sql.Conn) error {
  90. return nil
  91. }
  92. // DBType
  93. func (m *BaseUndoLogManager) DBType() types.DBType {
  94. panic("implement me")
  95. }
  96. // HasUndoLogTable check undo log table if exist
  97. func (m *BaseUndoLogManager) HasUndoLogTable(ctx context.Context, conn *sql.Conn) (res bool, err error) {
  98. if _, err = conn.QueryContext(ctx, CheckUndoLogTableExistSql); err != nil {
  99. // 1146 mysql table not exist fault code
  100. if e, ok := err.(*mysql.SQLError); ok && e.Code == mysql.ErrNoSuchTable {
  101. return false, nil
  102. }
  103. log.Errorf("[HasUndoLogTable] query sql fail, err: %v", err)
  104. return
  105. }
  106. return true, nil
  107. }
  108. // getBatchDeleteUndoLogSql build batch delete undo log
  109. func (m *BaseUndoLogManager) getBatchDeleteUndoLogSql(xid []string, branchID []int64) (string, error) {
  110. if len(xid) == 0 || len(branchID) == 0 {
  111. return "", ErrorDeleteUndoLogParamsFault
  112. }
  113. var undoLogDeleteSql strings.Builder
  114. undoLogDeleteSql.WriteString(constant.DeleteFrom)
  115. undoLogDeleteSql.WriteString(constant.UndoLogTableName)
  116. undoLogDeleteSql.WriteString(" WHERE ")
  117. undoLogDeleteSql.WriteString(constant.UndoLogBranchXid)
  118. undoLogDeleteSql.WriteString(" IN ")
  119. m.appendInParam(len(branchID), &undoLogDeleteSql)
  120. undoLogDeleteSql.WriteString(" AND ")
  121. undoLogDeleteSql.WriteString(constant.UndoLogXid)
  122. undoLogDeleteSql.WriteString(" IN ")
  123. m.appendInParam(len(xid), &undoLogDeleteSql)
  124. return undoLogDeleteSql.String(), nil
  125. }
  126. // appendInParam build in param
  127. func (m *BaseUndoLogManager) appendInParam(size int, str *strings.Builder) {
  128. if size <= 0 {
  129. return
  130. }
  131. str.WriteString(" (")
  132. for i := 0; i < size; i++ {
  133. str.WriteString("?")
  134. if i < size-1 {
  135. str.WriteString(",")
  136. }
  137. }
  138. str.WriteString(") ")
  139. }