Skip to content

Commit

Permalink
add seata-go tcc example (#418)
Browse files Browse the repository at this point in the history
* add seata-go tcc example

* add seata-go tcc example

* format

* format

Co-authored-by: xubaisheng <>
  • Loading branch information
betterwinsone authored Oct 16, 2022
1 parent c0df13b commit 46d46de
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 57 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* proxyless: give an proxyless service mesh example which shows how to deploy the dubbo-go services on kubernetes platform
* registry: show how to use etcd/nacos/polaris/zookeeper as dubbogo registry
* rpc: dubbo directory display dubbo protocol communication
* seata: A seata example
* seata-go: A seata-go example
* skywalking: show how to integrate skywalking into dubbogo
* tracing: tracing example

Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* proxyless: 这个示例演示了如何将 dubbo-go 开发的应用部署在 Istio 体系下,以实现 Envoy 对 dubbo/dubbo-go 服务的自动代理
* registry: 把 etcd/nacos/polaris/zookeeper 当做 dubbogo 注册中心示例
* rpc: 使用 Dubbogo 框架启动 rpc 服务,发起调用
* seata: 在 dubbogo 中如何基于 seata 实现分布式事务
* seata-go: 在 dubbogo 中如何基于 seata-go 实现分布式事务
* skywalking: 整合 skywalking 与 dubbogo 的示例
* tracing: 链路追踪例子,支持

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
go.opentelemetry.io/otel/sdk v1.10.0
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1
github.com/seata/seata-go v0.1.0-rc1
)

go 1.15
79 changes: 24 additions & 55 deletions go.sum

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions seata-go/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

version: '3'
services:
seata-server:
image: seataio/seata-server:1.5.2
ports:
- "8091:8091"
- "7091:7091"
environment:
- SEATA_PORT=8091
- STORE_MODE=file

zookeeper:
image: zookeeper
ports:
- "2181:2181"
restart: on-failure
12 changes: 12 additions & 0 deletions seata-go/tcc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Seata-go tcc example

## How to run

1. Start the seata-server and zookeeper service with the docker file

~~~shell
cd seata-go/tcc
docker-compose -f docker-compose.yml up -d seata-server zookeeper
~~~

2. Just execute the main function under tcc/client/cmd and tcc/server/cmd directory
70 changes: 70 additions & 0 deletions seata-go/tcc/client/cmd/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package main

import (
"context"
)

import (
"dubbo.apache.org/dubbo-go/v3/config"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"github.com/dubbogo/gost/log/logger"
_ "github.com/seata/seata-go/pkg/imports"
"github.com/seata/seata-go/pkg/integration"
"github.com/seata/seata-go/pkg/rm/tcc"
"github.com/seata/seata-go/pkg/tm"
)

import (
"github.com/apache/dubbo-go-samples/seata-go/tcc/client/service"
)

// need to setup environment variable "DUBBO_GO_CONFIG_PATH" to "seata-go/tcc/client/conf/dubbogo.yml"
//and run "seata-go/tcc/server/cmd/server.go" before run
func main() {
integration.UseDubbo()
config.SetConsumerService(service.UserProviderInstance)
err := config.Load()
if err != nil {
panic(err)
}
test()
}

func test() {
var err error
ctx := tm.Begin(context.Background(), "TestTCCServiceBusiness")
defer func() {
resp := tm.CommitOrRollback(ctx, err == nil)
logger.Infof("tx result %v", resp)
<-make(chan struct{})
}()

userProviderProxy, err := tcc.NewTCCServiceProxy(service.UserProviderInstance)
if err != nil {
logger.Infof("userProviderProxyis not tcc service")
return
}
resp, err := userProviderProxy.Prepare(ctx, 1)
if err != nil {
logger.Infof("response prepare: %v", err)
return
}
logger.Infof("get resp %#v", resp)
}
32 changes: 32 additions & 0 deletions seata-go/tcc/client/conf/dubbogo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# dubbo client yaml configure file
dubbo:
registries:
demoZK:
protocol: zookeeper
address: 127.0.0.1:2181
consumer:
filter: seataDubboFilter
references:
UserProvider:
protocol: dubbo
interface: com.github.seata.sample.UserProvider
logger:
zap-config:
level: info
37 changes: 37 additions & 0 deletions seata-go/tcc/client/service/user_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package service

import (
"context"
)

import (
"github.com/seata/seata-go/pkg/tm"
)

var (
UserProviderInstance = &UserProvider{}
)

type UserProvider struct {
Prepare func(ctx context.Context, params ...interface{}) (bool, error) `seataTwoPhaseAction:"prepare" seataTwoPhaseServiceName:"TwoPhaseDemoService"`
Commit func(ctx context.Context, businessActionContext *tm.BusinessActionContext) (bool, error) `seataTwoPhaseAction:"commit"`
Rollback func(ctx context.Context, businessActionContext *tm.BusinessActionContext) (bool, error) `seataTwoPhaseAction:"rollback"`
GetActionName func() string
}
82 changes: 82 additions & 0 deletions seata-go/tcc/server/cmd/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package main

import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)

import (
"dubbo.apache.org/dubbo-go/v3/config"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"github.com/dubbogo/gost/log/logger"
_ "github.com/seata/seata-go/pkg/imports"
"github.com/seata/seata-go/pkg/integration"
"github.com/seata/seata-go/pkg/rm/tcc"
)

import (
"github.com/apache/dubbo-go-samples/seata-go/tcc/server/service"
)

// need to setup environment variable "DUBBO_GO_CONFIG_PATH" to "seata-go/tcc/server/conf/dubbogo.yml" before run
func main() {
integration.UseDubbo()
userProviderProxy, err := tcc.NewTCCServiceProxy(&service.UserProvider{})
if err != nil {
logger.Errorf("get userProviderProxy tcc service proxy error, %v", err.Error())
return
}
// server should register resource
err = userProviderProxy.RegisterResource()
if err != nil {
logger.Errorf("userProviderProxy register resource error, %v", err.Error())
return
}
config.SetProviderService(userProviderProxy)
if err := config.Load(); err != nil {
panic(err)
}
initSignal()
}

func initSignal() {
signals := make(chan os.Signal, 1)
// It is not possible to block SIGKILL or syscall.SIGSTOP
signal.Notify(signals, os.Interrupt, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
sig := <-signals
logger.Infof("get signal %s", sig.String())
switch sig {
case syscall.SIGHUP:
// reload()
default:
time.AfterFunc(time.Duration(int(3e9)), func() {
logger.Warnf("app exit now by force...")
os.Exit(1)
})
// The program exits normally or timeout forcibly exits.
fmt.Println("provider app exit now...")
return
}
}
}
36 changes: 36 additions & 0 deletions seata-go/tcc/server/conf/dubbogo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# dubbo server yaml configure file
dubbo:
registries:
demoZK:
protocol: zookeeper
timeout: 3s
address: 127.0.0.1:2181
protocols:
dubbo:
name: dubbo
port: 20000
provider:
services:
UserProvider:
interface: com.github.seata.sample.UserProvider
filter: seataDubboFilter
logger:
zap-config:
level: info
50 changes: 50 additions & 0 deletions seata-go/tcc/server/service/user_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package service

import (
"context"
)

import (
"github.com/dubbogo/gost/log/logger"
"github.com/seata/seata-go/pkg/tm"
)

type UserProvider struct {
}

func (t *UserProvider) Prepare(ctx context.Context, params ...interface{}) (bool, error) {
logger.Infof("Prepare result: %v, xid %v", params, tm.GetXID(ctx))
return true, nil
}

func (t *UserProvider) Commit(ctx context.Context, businessActionContext *tm.BusinessActionContext) (bool, error) {
logger.Infof("Commit result: %v, xid %s", businessActionContext, tm.GetXID(ctx))
return true, nil
}

func (t *UserProvider) Rollback(ctx context.Context, businessActionContext *tm.BusinessActionContext) (bool, error) {
logger.Infof("Rollback result: %v, xid %s", businessActionContext, tm.GetXID(ctx))
return true, nil
}

func (t *UserProvider) GetActionName() string {
logger.Infof("GetActionName result")
return "TwoPhaseDemoService"
}

0 comments on commit 46d46de

Please sign in to comment.