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.

transactional_template.go 2.7 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package executor
  2. import (
  3. "context"
  4. "github.com/pkg/errors"
  5. "github.com/seata/seata-go/pkg/common/log"
  6. "github.com/seata/seata-go/pkg/protocol/transaction"
  7. "github.com/seata/seata-go/pkg/protocol/transaction/manager"
  8. "sync"
  9. )
  10. type TransactionalExecutor interface {
  11. Execute(ctx context.Context, param interface{}) (interface{}, error)
  12. GetTransactionInfo() transaction.TransactionInfo
  13. }
  14. var (
  15. transactionTemplate *TransactionTemplate
  16. onceTransactionTemplate = &sync.Once{}
  17. )
  18. func GetTransactionTemplate() *TransactionTemplate {
  19. if transactionTemplate == nil {
  20. onceTransactionTemplate.Do(func() {
  21. transactionTemplate = &TransactionTemplate{}
  22. })
  23. }
  24. return transactionTemplate
  25. }
  26. type TransactionTemplate struct {
  27. }
  28. func (t *TransactionTemplate) Execute(ctx context.Context, business TransactionalExecutor, param interface{}) (interface{}, error) {
  29. if !transaction.IsSeataContext(ctx) {
  30. err := errors.New("context should be inited as seata context!")
  31. log.Error(err)
  32. return nil, err
  33. }
  34. if transaction.GetTransactionRole(ctx) == nil {
  35. transaction.SetTransactionRole(ctx, transaction.LAUNCHER)
  36. }
  37. var tx *manager.GlobalTransaction
  38. if transaction.HasXID(ctx) {
  39. tx = &manager.GlobalTransaction{
  40. Xid: transaction.GetXID(ctx),
  41. Status: transaction.Begin,
  42. Role: transaction.PARTICIPANT,
  43. }
  44. }
  45. // todo: Handle the transaction propagation.
  46. if tx == nil {
  47. tx = &manager.GlobalTransaction{
  48. Xid: transaction.GetXID(ctx),
  49. Status: transaction.UnKnown,
  50. Role: transaction.LAUNCHER,
  51. }
  52. }
  53. // todo: set current tx config to holder
  54. // begin global transaction
  55. err := t.BeginTransaction(ctx, tx, business.GetTransactionInfo().TimeOut, business.GetTransactionInfo().Name)
  56. if err != nil {
  57. log.Infof("transactionTemplate: begin transaction failed, error %v", err)
  58. return nil, err
  59. }
  60. // do your business
  61. res, err := business.Execute(ctx, param)
  62. if err != nil {
  63. log.Infof("transactionTemplate: execute business failed, error %v", err)
  64. return nil, manager.GetGlobalTransactionManager().Rollback(ctx, tx)
  65. }
  66. // commit global transaction
  67. err = t.CommitTransaction(ctx, tx)
  68. if err != nil {
  69. log.Infof("transactionTemplate: commit transaction failed, error %v", err)
  70. // rollback transaction
  71. return nil, manager.GetGlobalTransactionManager().Rollback(ctx, tx)
  72. }
  73. return res, err
  74. }
  75. func (TransactionTemplate) BeginTransaction(ctx context.Context, tx *manager.GlobalTransaction, timeout int32, name string) error {
  76. return manager.GetGlobalTransactionManager().Begin(ctx, tx, timeout, name)
  77. }
  78. func (TransactionTemplate) CommitTransaction(ctx context.Context, tx *manager.GlobalTransaction) error {
  79. return manager.GetGlobalTransactionManager().Commit(ctx, tx)
  80. }

Go Implementation For Seata