在服务层中使用 TransactionScope 进行 UnitOfWork 操作

发布于 2024-10-16 20:06:41 字数 2343 浏览 2 评论 0原文

我的方法是否正确地将所有 3 个 dataprovider.GetXXX 方法捆绑在服务层中的 TransactionScope 中作为 UnitOfWork?

你会做一些不同的事情吗?

TransactionScpe ts从哪里知道具体的ConnectionString?

我应该从连接中获取 Transaction 对象并将此 Transaction 对象传递给 TransactionScope 的构造函数吗?

服务层,如 AdministrationService.cs

private List<Schoolclass> GetAdministrationData()
{

   List<Schoolclass> schoolclasses = null
   using (TransactionScope ts = new TransactionScope())
                    {
                        schoolclasses = _adminDataProvider.GetSchoolclasses();
                        foreach (var s in schoolclasses)
                        {
                           List<Pupil> pupils = _adminDataProvider.GetPupils(s.Id);
                           s.Pupils = pupils;

                           foreach (var p in pupils)
                           {
                               List<Document> documents = _documentDataProvider.GetDocuments(p.Id);
                               p.Documents = documents;
                           }
                        } 

                        ts.Complete();
                    }


   return schoolclasses;
}

DataProvider 中这 3 个方法中的任何一个的示例:

public List<Schoolclass> GetSchoolclassList()
        {
            // used that formerly without TransactionSCOPE => using (var trans = DataAccess.ConnectionManager.BeginTransaction())
            using (var com = new SQLiteCommand(DataAccess.ConnectionManager))
            {
                com.CommandText = "SELECT * FROM SCHOOLCLASS";

                var schoolclasses = new List<Schoolclass>();

                using (var reader = com.ExecuteReader())
                {
                    Schoolclass schoolclass = null;
                    while (reader.Read())
                    {
                        schoolclass = new Schoolclass();
                        schoolclass.SchoolclassId = Convert.ToInt32(reader["schoolclassId"]);
                        schoolclass.SchoolclassCode = reader["schoolclasscode"].ToString();
                        schoolclasses.Add(schoolclass);
                    }
                }
                // Used that formerly without TransactionSCOPE => trans.Commit();
                return schoolclasses;
            }
        }

Is my approach right to bundle all 3 dataprovider.GetXXX methods in a TransactionScope in the service layer as UnitOfWork?

Would you do something different?

From where does the TransactionScpe ts know the concrete ConnectionString?

Should I get the Transaction object from my connection and pass this Transaction objekt to the constructor of the TransactionScope ?

Service Layer like AdministrationService.cs

private List<Schoolclass> GetAdministrationData()
{

   List<Schoolclass> schoolclasses = null
   using (TransactionScope ts = new TransactionScope())
                    {
                        schoolclasses = _adminDataProvider.GetSchoolclasses();
                        foreach (var s in schoolclasses)
                        {
                           List<Pupil> pupils = _adminDataProvider.GetPupils(s.Id);
                           s.Pupils = pupils;

                           foreach (var p in pupils)
                           {
                               List<Document> documents = _documentDataProvider.GetDocuments(p.Id);
                               p.Documents = documents;
                           }
                        } 

                        ts.Complete();
                    }


   return schoolclasses;
}

Sample how any of those 3 methods in the DataProvider could look like:

public List<Schoolclass> GetSchoolclassList()
        {
            // used that formerly without TransactionSCOPE => using (var trans = DataAccess.ConnectionManager.BeginTransaction())
            using (var com = new SQLiteCommand(DataAccess.ConnectionManager))
            {
                com.CommandText = "SELECT * FROM SCHOOLCLASS";

                var schoolclasses = new List<Schoolclass>();

                using (var reader = com.ExecuteReader())
                {
                    Schoolclass schoolclass = null;
                    while (reader.Read())
                    {
                        schoolclass = new Schoolclass();
                        schoolclass.SchoolclassId = Convert.ToInt32(reader["schoolclassId"]);
                        schoolclass.SchoolclassCode = reader["schoolclasscode"].ToString();
                        schoolclasses.Add(schoolclass);
                    }
                }
                // Used that formerly without TransactionSCOPE => trans.Commit();
                return schoolclasses;
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流星番茄 2024-10-23 20:06:41

这看起来不错 - 这就是 TransactionScope 的用途,在代码中提供事务控制(这是 UoW 的常见模式)。

TransactionScpe ts从哪里知道具体的ConnectionString?

事实并非如此。这取决于您的数据访问层,对于 TransactionScope 来说并没有多大意义。 TransactionScope 的作用是创建一个事务(默认情况下是一个轻量级事务) - 如果您的数据访问跨越多个数据库,该事务将自动升级为分布式事务。它在底层使用 MSDTC。

我应该从连接中获取 Transaction 对象并将该 Transaction 对象传递给 TransactionScope 的构造函数吗?

不,不,不。参见上文。就做你现在正在做的事吧。嵌套 TransactionScope 没有什么坏处。

This looks fine - that's what TransactionScope is there for, to provide transaction control in your code (and this is a common pattern for UoW).

From where does the TransactionScpe ts know the concrete ConnectionString?

It doesn't. That depends on your data access layer and doesn't really mean much to TransactionScope. What TransactionScope does is create a transaction (which will by default be a light-weight one) - if your data access spans several databases, the transaction will automatically be escalated to a distributed transaction. It uses MSDTC under the hood.

Should I get the Transaction object from my connection and pass this Transaction objekt to the constructor of the TransactionScope ?

No, no, no. See the above. Just do what you are doing now. There is no harm in nesting TransactionScopes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文