[英]Share IDbConnection to keep transaction local
數據存儲庫(用於處理數據實體從通用接口繼承的數據)和DAL層被實現為通用類,該類將通用接口作為依賴項注入獲得。 以下是設計:
數據實體-車輛
public class Vehicle
{
public int Id {get; set;}
public string Brand {get; set;}
}
通用接口-IData
public interface IData<T>
{
IEnumerable<T> Select(IDictionary<string,object> parameters);
int Update(IDictionary<string,object> parameters);
int Delete(IDictionary<string,object> parameters);
int insert(IDictionary<string,object> parameters);
}
車輛資料庫
public class VehicleData : IData<Vehicle>
{
IEnumerable<Vehicle> Select(IDictionary<string,object> parameters)
{
using(IDbConnection conn = (Fetch Connection))
{
// Select Operation
}
}
int Update(IDictionary<string,object> parameters)
{
using(IDbConnection conn = (Fetch Connection))
{
// Update Operation
}
}
int Delete(IDictionary<string,object> parameters)
{
using(IDbConnection conn = (Fetch Connection))
{
// Delete Operation
}
}
int insert(IDictionary<string,object> parameters)
{
using(IDbConnection conn = (Fetch Connection))
{
// Insert Operation
}
}
}
DAL類的實現:
public class DAL<T>
{
public static IEnumerable<T> Select(IData<T> dataRepository, IDictionary<string,object> parameters)
{
return dataRepository.Select(parameters);
}
// Implementation for Insert, Update and Delete
}
我從調用類使用DAL
執行VehicleData
,如下所示。
IData<Vehicle> vehicleData = new VehicleData();
IDictionary<string,object> parameters = // Filled from client
DAL<Vehicle>.Select(vehicleData,parameters);
我面臨的問題是,在每種CRUD方法中,IDbConnection是在Using
塊中創建的,因此最終放置在本地上下文中,就像在本地上下文中一樣,但是在某些情況下,對各個實體的多個DAL操作需要成為單個事務的一部分在上下文中,如果我以類似的方式繼續進行操作,那么打開的事務上下文將被提升到分布式級別,因為打開了多個連接資源,即使我可以在它們一個接一個地執行的相同連接上下文中進行操作也是如此。 問題仍然存在:
如何在多個調用之間共享連接,例如DAL<Vehicle>.Update, DAL<Driver>.Update and DAL<Truck>.Update
,這樣可以避免從本地到分布式的事務升級
不確定,在事務上下文中打開和處理連接是否意味着可以打開另一個連接而無需升級為分布式事務,我認為這不會發生
您是否正在使用IoC容器進行依賴項注入? 在IoC中,有一些生活方式(每個線程,每個Web請求等),例如,在城堡溫莎中,您可以使用Scoped生活方式 。 您的代碼將如下所示:
創建連接(linq2db):
container.Register(
Component.For<DataConnection>().UsingFactoryMethod(x =>
CreateDataConnection()).LifestyleScoped(),
Component.For<IData<Vehicle>>()
.ImplementedBy<VehicleData>().LifestyleScoped()
);
private static DataConnection CreateDataConnection()
{
return new DataConnection(new SqlServerDataProvider("", SqlServerVersion.v2008),
@"Data Source=(local);Initial Catalog=DB1;Persist Security Info=True;User ID=user;Password=pwd");
}
做一些數據庫操作:
using (container.BeginScope())
{
var db = container.Resolve<DataConnection>();
db.BeginTransaction();
container.Resolve<IData<Vehicle>>().Update(...);
container.Resolve<IData<Vehicle>>().Update(...);
container.Resolve<IData<Vehicle>>().Update(...);
db.CommitTransaction();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.