Мне было интересно, каков наилучший способ или практика для реализации следующего:
У меня есть метод с именем EditUser, который имеет следующее определение:
public void EditUser(user user, Roles role)
{
using (TestEntities entities = new TestEntities())
{
entities.Connection.Open();
using (DbTransaction trans = entities.Connection.BeginTransaction())
{
try
{
var tmpUser = entities.users.Where(fields => fields.UserId == user.UserId).FirstOrDefault();
RoleManagement rm = new RoleManagement();
string oldRole = tmpUser.roles.FirstOrDefault().Name;
string newRole = rm.GetRoleName(role);
if (oldRole == newRole)
{
entities.users.ApplyCurrentValues(user);
}
else
{
rm.UnbindRoles(tmpUser.UserId, entities.Connection);
this.DeleteUser(tmpUser.UserId, entities.Connection);
this.Register(user, role, entities.Connection);
}
entities.SaveChanges();
trans.Commit();
}
catch (Exception ex)
{
trans.Rollback();
throw ex;
}
}
}
}
Как вы можете заметить, я вызываю несколько методов: UnbindRoles, DeleteUser и RegisterUser, где все они должны быть запущены в рамках одной транзакции (той же транзакции, которую выполняет EditUser), в случае сбоя чего-либо мне потребуется выполнить откат.
Теперь моя проблема в основном здесь ... метод RegisterUser также запускает новую транзакцию, поскольку он добавляет пользователя и назначает новому пользователю роль.
Кто-нибудь может описать лучший способ, как это реализовать? Я попытался использовать блок TransactionScope, но он не работает, так как я запускаю это приложение в среде Medium Trust
EDIT
Подтверждение того, что поставщик коннектора MySQL .NET имеет ошибку при использовании TransactionScope в Medium Trust, поскольку я только что проверил сейчас тот же сценарий с использованием базы данных MS SQL Server, и он работает без каких-либо проблем