该代码的用途是使调用EF的dbContext相关操作时,将具体方法用最低隔离级别的事务包裹起来执行,达到类似with(nolock)的效果。为了使其通用,写了以下代码。但不知道是否可以用什么方法把该代码写的更精简。
public static class EFHelper { public static T2 Invoke<T1, T2>(Func<T1, T2> func, T1 t1) { var opt = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }; T2 res = default(T2); using (var sc = new System.Transactions.TransactionScope(TransactionScopeOption.Required, opt)) { try { res = func(t1); sc.Complete(); } catch (Exception) { sc.Dispose(); throw; } } return res; } public static T3 Invoke<T1, T2, T3>(Func<T1, T2, T3> func, T1 t1, T2 t2) { var opt = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }; T3 res = default(T3); using (var sc = new System.Transactions.TransactionScope(TransactionScopeOption.Required, opt)) { try { res = func(t1, t2); sc.Complete(); } catch (Exception) { sc.Dispose(); throw; } } return res; } public static T1 Invoke<T1>(Func<T1> func) { var opt = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }; T1 res = default(T1); using (var sc = new System.Transactions.TransactionScope(TransactionScopeOption.Required, opt)) { try { res = func(); sc.Complete(); } catch (Exception) { sc.Dispose(); throw; } } return res; } public static void Invoke<T1>(Action<T1> action, T1 t1) { var opt = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }; using (var sc = new System.Transactions.TransactionScope(TransactionScopeOption.Required, opt)) { try { action(t1); sc.Complete(); } catch (Exception) { sc.Dispose(); throw; } } } public static void Invoke(Action action) { var opt = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }; using (var sc = new System.Transactions.TransactionScope(TransactionScopeOption.Required, opt)) { try { action(); sc.Complete(); } catch (Exception) { sc.Dispose(); throw; } } } }
你是在搞笑吗,晕死了都
你晕啥
不切实际,
Action<int> delAction = (x) =>
{
var db = new Entities();
//do work
};
EFHelper.Invoke(delAction, ID);
我可以这样调用;否则要写这么多代码:
public static void Invoke<T1>(Action<T1> action, T1 t1)
{
var opt = new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted };
using (var sc = new System.Transactions.TransactionScope(TransactionScopeOption.Required, opt))
{
try
{
var db = new Entities();
//do work
sc.Complete();
}
catch (Exception)
{
sc.Dispose();
throw;
}
}
}
你为什么说不切实际呢??
@Tony Tan: 首先nolock很不好
然后最好不要用分布式事务
@吴瑞祥: 恩,是的。不过我们公司要求这样,即使写sql,任何时候都要加上with(nolock)。另外此处未涉及到分布式事务。
我是想问,如果那位熟悉设计模式的,该代码是否可以优化,跟踪参数的个数和是否含返回类型,可能需要很多个重载。
@Tony Tan: 是查询的时候要加上nolock吧,事务操作的时候加nolock怎么保证一致性?
尤其像你这样搞,怎么保证不出并发错误,
System.Transactions.TransactionScope 就是分布式事务。
@吴瑞祥: 有什么并发错误?只是select出来的有脏数据而已,脏数据是允许的,但是影响关键业务的性能是不允许的。用这个nolock的是非关键业务。
System.Transactions.TransactionScope 不一定是分布式事务。只有资源分布在不同的机器才存在分布式事务。