在服务层中使用 TransactionScope 进行 UnitOfWork 操作
我的方法是否正确地将所有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这看起来不错 - 这就是
TransactionScope
的用途,在代码中提供事务控制(这是 UoW 的常见模式)。事实并非如此。这取决于您的数据访问层,对于
TransactionScope
来说并没有多大意义。TransactionScope
的作用是创建一个事务(默认情况下是一个轻量级事务) - 如果您的数据访问跨越多个数据库,该事务将自动升级为分布式事务。它在底层使用 MSDTC。不,不,不。参见上文。就做你现在正在做的事吧。嵌套
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).It doesn't. That depends on your data access layer and doesn't really mean much to
TransactionScope
. WhatTransactionScope
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.No, no, no. See the above. Just do what you are doing now. There is no harm in nesting
TransactionScope
s.