ホームページ  >  記事  >  バックエンド開発  >  Gorm トランザクション エラー error = トランザクションがコミットまたはロールバックされました

Gorm トランザクション エラー error = トランザクションがコミットまたはロールバックされました

WBOY
WBOY転載
2024-02-10 23:09:07568ブラウズ

Gorm 事务错误 error = 事务已提交或回滚

php エディターの Youzi は、この記事で「Gorm トランザクション エラー エラー = トランザクションがコミットまたはロールバックされました」という一般的なエラー メッセージを紹介します。データベース操作に Gorm を使用すると、混乱を招くこのエラーが発生することがあります。この記事では、読者がこの問題を解決してデータベース操作をスムーズに実行できるように、このエラーの原因と考えられる解決策を詳しく説明します。

質問内容

私の目標は、以下のコードでトランザクション管理を行うことです。いずれかの戦略で問題が発生した場合は、ロールバックしようとします。コードをテストしているときに、ロールバックまたはコミット コマンドを 1 回実行すると、エラー = トランザクションが 2 回目にコミットまたはロールバックされたというエラーが発生することに気付きました。このエラーを修正するにはどうすればよいですか?

func (d *DistributeService) Distribute(vehicleNumberPlate string, request model.DistributeRequest) (*model.DistributeResponse, error) {
    var response model.DistributeResponse
    response.Vehicle = vehicleNumberPlate
    var routeList []model.RouteResponse
    tx := d.repo.BeginTransaction()
    for _, routes := range request.RouteRequest {
        var routeResponse model.RouteResponse
        strategy, isStrategyExists := d.strategies[routes.DeliveryPoint]
        if isStrategyExists {
            resp, err := strategy.Distribute(routes.Deliveries, vehicleNumberPlate, tx)
            if err != nil {
                tx.Rollback()
                logrus.Errorf("Error while distributing: %v", err)
                return nil, err
            }
            routeResponse.DeliveryPoint = routes.DeliveryPoint
            routeResponse.Deliveries = *resp
            routeList = append(routeList, routeResponse)
        } else {
            logrus.Errorf("Invalid delivery point: %v", routes.DeliveryPoint)
            return nil, errors.New("invalid delivery point")
        }
    }
    response.RouteResponse = routeList
    err := d.checkSackPackagesAreUnloaded()
    tx.Commit()
    if err != nil {
        return nil, err
    }
    return &response, nil
}

回避策

各呼び出しで同じトランザクション オブジェクトを使用している可能性があります。 何らかの理由で一度閉じられた場合は、新しいトランザクション オブジェクトを作成する必要があります。

あなたがおそらく質問したのと同じトランザクション オブジェクトを使用していると私が言うのはなぜですか? 基本的にポインタを d *DistributeService に渡しているためです。 次に、 tx := d.repo.BeginTransaction() を使用します。このコードが何をするのかはわかりませんが、以降の実行では同じトランザクション オブジェクトを返していることは間違いありません。

解決策は、Documentation で説明されているように、たとえば tx := db.Begin() を使用して、このメソッドが呼び出されるたびに新しいトランザクション オブジェクトを作成することです。

以上がGorm トランザクション エラー error = トランザクションがコミットまたはロールバックされましたの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。