从源码角度看Transaction以及如何手工接管Transaction实现高度的自定义化

一:transaction

CUD: 在一个transaction中。。。

transaction: start

add....

delete...

update...

transaction: commit /rollback

 

R: nontransction 【无事务操作】


《1》验证:SaveChanges方法中做到的。。。


检测是是否开启事务的最好方式: Log接口 。。。 => Database下面


int num = this.ExecuteInTransaction<int>(() => this._adapter.Update(), executionStrategy, startLocalTransaction, true);

internal virtual T ExecuteInTransaction<T>(Func<T> func, IDbExecutionStrategy executionStrategy, bool startLocalTransaction, bool releaseConnectionOnSuccess)
{
T local2;
this.EnsureConnection(startLocalTransaction);
bool flag = false;
EntityConnection connection = (EntityConnection) this.Connection;
if (((connection.CurrentTransaction == null) && !connection.EnlistedInUserTransaction) && (this._lastTransaction == null))
{
flag = startLocalTransaction;
}
else if ((executionStrategy != null) && executionStrategy.RetriesOnFailure)
{
throw new InvalidOperationException(System.Data.Entity.Resources.Strings.ExecutionStrategy_ExistingTransaction(executionStrategy.GetType().Name));
}
DbTransaction transaction = null;
try
{
if (flag)
{
transaction = connection.BeginTransaction();
}
T local = func();
if (transaction != null)
{
transaction.Commit();
}
if (releaseConnectionOnSuccess)
{
this.ReleaseConnection();
}
local2 = local;
}
catch (Exception)
{
this.ReleaseConnection();
throw;
}
finally
{
if (transaction != null)
{
transaction.Dispose();
}
}
return local2;
}

《2》 Query操作的业务逻辑。。

flag=false 所以没有执行。。。

try
{
if (flag)
{
dbTransaction = entityConnection.BeginTransaction();
}
T t = func();
if (dbTransaction != null)
{
try
{
dbTransaction.Commit();
}
catch (Exception innerException)
{
throw new CommitFailedException(Strings.CommitFailed, innerException);
}
}
if (releaseConnectionOnSuccess)
{
this.ReleaseConnection();
}
result = t;
}
catch (Exception)
{
this.ReleaseConnection();
throw;
}
finally
{
if (dbTransaction != null)
{
dbTransaction.Dispose();
}
}


三:接管

自己接管有什么好处????

1. 高度的自定义化, 某些操作一个事务,某些操作另一个事务。。。。

2. 改变事务的隔离级别: Commit Read /UnCommit Read (未提交读)

select * from student with (nolock) where .....

效率不是第一位,死锁在第一位。。。

set transaction isolation level read committed //S【Share】锁 IS【锁】

如果一个记录上有一个S锁,那么Insert是进不去了。。。IX

如果加上nolock,我们的insert,update将不会受到影响。。。。 高并发的情况下采取的一个措施。


3.

using (SchoolDBEntities db = new SchoolDBEntities())
{
using (var transaction=db.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{
try
{
// add.update...
db.Database.Log = Console.WriteLine;

var query = db.Students.FirstOrDefault();

db.SaveChanges();

transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
}
}
}


4. TransactionScope

using (SchoolDBEntities db = new SchoolDBEntities())
{
using (var transaction=new TransactionScope())
{
try
{
// add.update...
db.Database.Log = Console.WriteLine;

var query = db.Students.FirstOrDefault();

db.SaveChanges();

transaction.Complete();

}
catch (Exception ex)
{
Transaction.Current.Rollback();
}
}
}

 

posted @ 2017-03-13 23:31  dragon.net  阅读(556)  评论(0编辑  收藏  举报