我使用Ninject作为我的IOC。我有两个课程,如下所示。
客户:
public class Customer:ICustomer
{
private ICustomerRepository _CustRepo;
public Customer(ICustomerRepository custRepo){
_CustRepo = custRepo;
}
public void CustomerOperations(int custId){
var cust = _CustRepo.GetCustomer(custId);
//Do something with the cust object
if(condition1)
_CustRepo.Update(cust);
if(condition2)
_CustRepo.Delete(cust.id);
if(condition3)
_CustRepo.Insert(cust);
}
}
存储库:
public class CustomerRepository:ICustomerRepository {
private IDataAccessLayer _Dal;
//Ctor details skipped
public Customer GetCustomer(int custId) {//Get customer from DB}
public bool Update(Customer c) {//Update}
public bool Delete(int custID) {//Delete}
public bool Insert(Customer c) {//Insert}
}
绑定:
Bind<ICustomer>().To<Customer>().InThreadScope();
Bind<ICustomerRepository>().To<CustomerRepository>().InSingletonScope();
我们假设范围无法改变。我正在尝试同步调用,因此当thread2准备更新同一客户时,thread1不会删除客户。
如果建议使用锁定,我如何确保存储库方法是线程安全的。谢谢
答案 0 :(得分:0)
这是锁定无法解决的并发问题。
请考虑以下事项: 客户端A在客户端B可以进行删除之前请求删除客户。在这种情况下会发生以下情况:
查看基础数据存储的concurrency control机制。
如果您使用的是SQL Server + EF,请查看此article。
答案 1 :(得分:0)
正如MattTannahill所说,这是一个并发问题。
实现您想要完成的任务的唯一方法是推迟执行不返回的实际点(更新/删除),并在此之前进行正确的簿记,以提供足够的信息来执行正确的序列或操作序列......由于缺乏更好的解释,您将从记录操作方程中删除并发。
所以基本上,你有一个与记录相关联的“事务日志/跟踪”,并且记录的实际操作直到稍后安全才会发生。与此同时,记录以“待更新”状态存储。
当然,这会打开你需要解决的其他事情,而且很快就会无法管理:
如何显示尚未执行操作的更新/删除记录。
最终说什么交易?你在这里暗示的是更新应该取消并发删除。如果您等待执行所有操作并分析事务跟踪,则可以执行此操作。这种事情的规则随着时间的推移会变得非常复杂,因为你必须从客户端交互的角度来“标记操作的记录”,然后是一个过程作业,以便以后实际分析和执行操作。 / p>
如果更新“取消”删除,由于操作稍后进行,因此没有立即让用户知道它没有删除的方法。你必须想办法让这个用户知道。
您需要定义执行这些修改的“安全”时间。你没有记录活动30秒后这样做吗?是否存在始终优先的某些修改?