Но что будет если на клиенте что-то произойдет и транзакция останется незакрытой?
Как быть, если каждый метод в текущей реализации открывает свое собственное соединение с базой, причем базы могут быть разные.
Здравствуйте, Chardex, Вы писали:
C>Есть клиент-серверное приложение, хочу выполнять методы сервера с клиента в рамках транзакции, но не знаю как правильно это реализовать. C>Например:
C>Но что будет если на клиенте что-то произойдет и транзакция останется незакрытой?
Например, можно настроить на Rollback по прошествии некоторого таймаута.
C>Как быть, если каждый метод в текущей реализации открывает свое собственное соединение с базой, причем базы могут быть разные.
Если базы разные то, использование их в одной транзакции скорее всего потребует использования DTC. Классы из System.Transactions уже это умеют. На BeginTransaction надо создать транзакцию и где-то ее запомнить. А при каждом последующем вызове обращаться к базе именно в контексте запомненной транзакции...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, Chardex, Вы писали:
C>Есть клиент-серверное приложение, хочу выполнять методы сервера с клиента в рамках транзакции, но не знаю как правильно это реализовать. C>Например:
C>Но что будет если на клиенте что-то произойдет и транзакция останется незакрытой? C>Как быть, если каждый метод в текущей реализации открывает свое собственное соединение с базой, причем базы могут быть разные.
connection.BeginTransaction();// Не надо её в try - вдруг сам этот вызов бросит исключение?
C>try
C>{
C> connection.Save(..);
C> connection.Remove(..);
C> connection.SomeMethod(...);
C> connection.CommitTransactiion();
C>}
C>finally
C>{
C> connection.RollbackTransaction(); // *
C>}
(*) А в вызове RollbackTransaction(); надо проверить, не была ли закомичена транзакция. Если этот вызов переделать нельзя, то надо написать свою обёртку по типу:
class TransactionHolder : IDisposable
{
private IConnection connection;
public TransactionHolder(IConnection connection) {
this.connection = connection;
}
public void Commit() {
if(connection == null) {
throw new InvalidOperationException("connection == null");
}//if
connection.CommitTransaction();
connection = null;
}
public void Roolback() {
if(connection != null) {
connection.RollbackTransaction();
connection = null;
}//if
}
public void Dispose() {
Rollback();
}
}
C>Но что будет если на клиенте что-то произойдет и транзакция останется незакрытой?
нормальный сервер БД должен откатить транзакцию при закрытии соединения, если она не была завершена
нормальный клиент должен заботиться о закрытии соединения, произойдет "что-то" или нет
C>Как быть, если каждый метод в текущей реализации открывает свое собственное соединение с базой, причем базы могут быть разные.
использовать COM+ (распределенные транзакции DTC)
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx