【问题标题】:ServiceStack Ormlite transaction between servicesServiceStack 服务之间的 Ormlite 事务
【发布时间】:2015-01-22 17:49:02
【问题描述】:

我在 ServiceStack 服务中执行相当复杂的保存操作时遇到问题。 为了简化解释,该服务启动一个 Ormlite 事务并在其中通过 ResolveService 调用另一个服务:

public ApplicationModel Post(ApplicationModel request)
{
    using (IDbTransaction tr = Db.OpenTransaction())
    {
        using (var cases = ResolveService<CaseService>())
        {
            request.Case = cases.Post(request.Case);
        }
    }
    Db.Save<Application>(request.Application, true);
}

另一个服务(CaseService)也使用事务来执行其逻辑:

public CaseModel Post(CaseModel request)
{
    using (IDbTransaction tr = Db.OpenTransaction())
    {
        Db.Insert<Case>(request);
        Db.SaveAllReferences<CaseModel>(request);
    }
}

在更高层次的服务调用其他服务的类似情况下,会引发“超时已过期”错误,尽管我密切监视 SQL Server 的死锁,但到目前为止我还无法解决。

我的问题是,这是否是跨服务使用/共享 Ormlite 事务的正确方式,还是有其他机制?

提前致谢。

【问题讨论】:

    标签: sql-server transactions servicestack ormlite-servicestack


    【解决方案1】:

    您不应该有嵌套事务,而不是跨服务调用来执行数据库操作,您应该使用单独的 shared Repository 或可重复使用的扩展方法提取共享逻辑:

    public static class DbExtensions
    {
        public static void SaveCaseModel(this IDbConnection db,
            CaseModel case)
        {
            db.Insert<Case>(case);
            db.SaveAllReferences<CaseModel>(case);
        }
    }
    

    然后您的服务可以维护自己的事务,同时能够共享逻辑,例如:

    public ApplicationModel Post(ApplicationModel request)
    {
        using (var trans = Db.OpenTransaction())
        {
            Db.SaveCaseModel(request.Case);
            Db.Save<Application>(request.Application, true);
            trans.Commit();
        }
    }
    
    public CaseModel Post(CaseModel request)
    {
        using (var trans = Db.OpenTransaction())
        {
            Db.SaveCaseModel(request);
            trans.Commit();
        }
    }
    

    【讨论】:

    • 我理解,实际上在服务中不仅仅是数据库操作,还有其他服务以及客户端请求的可重用逻辑。我需要将它转移到共享存储库上。我可以在服务之间共享事务吗? OrmliteConfig.TSTransaction 呢?
    • @gjspaho 当然,您可以共享同一个事务,只需构建它以避免嵌套事务。
    • 分享交易的最佳方式是什么?
    • @gjspaho 只需在顶级入口点 API 打开事务,不要嵌套它们,即任何共享逻辑都不应该启动它自己的事务。事务范围内的任何数据库操作都隐式地独立于该事务。
    • 如何测试打开的事务是否存在,服务注入的dbconnection的事务总是null。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多