Exception
вместо чего-то более конкретного)? И, во что бы то ни стало, не беспокойтесь на меня.
public void Export(Database dstDb)
{
try
{
using (DbConnection connection = dstDb.CreateConnection())
{
connection.Open();
DbTransaction transaction = connection.BeginTransaction();
try
{
// Export all data here (insert into dstDb)
transaction.Commit();
}
catch (SqlException sqlex)
{
ExceptionHelper.LogException(sqlex);
try
{
transaction.Rollback();
}
catch (Exception rollbackEx)
{
logger.Error("An exception of type " + rollbackEx.GetType() +
" was encountered while attempting to roll back the transaction.");
}
throw new Exception("Error exporting message " + Type + " #" + Id + ": [" + sqlex.GetType() + "] " + sqlex.Message, sqlex);
}
catch (Exception ex)
{
try
{
transaction.Rollback();
}
catch (Exception rollbackEx)
{
logger.Error("An exception of type " + rollbackEx.GetType() +
" was encountered while attempting to roll back the transaction.");
}
throw new Exception("Error exporting message " + Type + " #" + Id + ": [" + ex.GetType() + "] " + ex.Message, ex);
}
}
try
{
Status = MessageStatus.FINISHED;
srcDb.UpdateDataSet(drHeader.Table.DataSet, HEADERS,
CreateHeaderInsertCommand(), CreateHeaderUpdateCommand(), null);
}
catch (Exception statusEx)
{
logger.ErrorException("Failed to change message status to FINISHED: " +
Type + " #" + Id + ": " + statusEx.Message, statusEx);
}
}
catch (Exception importEx)
{
try
{
Status = MessageStatus.ERROR;
srcDb.UpdateDataSet(drHeader.Table.DataSet, HEADERS,
CreateHeaderInsertCommand(), CreateHeaderUpdateCommand(), null);
}
catch (Exception statusEx)
{
logger.ErrorException("Failed to change message status to ERROR: " +
Type + " #" + Id + ": " + statusEx.Message, statusEx);
}
AddErrorDescription(importEx.Message);
throw new Exception("Couldn't export message " + Type + " #" + Id + ", exception: " + importEx.Message, importEx);
}
}
Btw. Так много раз я очень старался быть настолько конкретным, насколько это возможно при формировании вопросов - в результате не было ни посещений, ни ответов, ни идеи, как решить проблему. На этот раз я думал обо всех случаях, когда кто-то еще интересовался моим вниманием, думаю, это было правильное дело:)
Update:
Я попытался применить некоторые советы, и вот что я до сих пор придумал. Я решил немного изменить поведение: когда невозможно установить статус сообщения FINISHED после успешного экспорта, я рассматриваю его как задание, которое не выполнено полностью, и я откатываюсь и выдаю исключение. Если вы, ребята, еще останетесь немного терпения, пожалуйста, сообщите мне, если это будет лучше. Или бросьте на меня еще одну критику. Btw. Спасибо за все ответы, я анализирую каждый из них.
Выбрасывание экземпляра System.Exception
не понравилось, поэтому я избавился от этого, как было предложено, и вместо этого решил ввести специальное исключение. Это, кстати, тоже не кажется правильным - излишним? Это выглядит хорошо с общедоступными методами, но немного переработано для частного участника, но все же я хочу знать, что возникла проблема с изменением статуса сообщения, а не с соединением с базой данных или чем-то.
Я вижу пару способов извлечения методов здесь, но все они, похоже, смешивают обязанности, которые jgauffin упоминаются в его комментарий: управление подключением к базе данных, обработка операций с базами данных, бизнес-логика (экспорт данных). Скажем, метод ChangeStatus
- это некоторый уровень абстракции - вы изменяете статус сообщения, и вас не интересует, как это происходит, как сохраняется сообщение и т.д. Возможно, мне следует использовать шаблон Data Mapper для дальнейшего отдельные обязанности, но в этом еще довольно простом сценарии я думал, что уйду с Active Record. Может быть, весь дизайн настолько запутан прямо сейчас, что я не вижу, где сделать разрезы?
public void Export(Database dstDb)
{
try
{
using (DbConnection connection = dstDb.CreateConnection())
{
connection.Open();
using (DbTransaction transaction = connection.BeginTransaction())
{
// Export all data here (insert into dstDb)
ChangeStatus(MessageStatus.FINISHED);
transaction.Commit();
}
}
}
catch (Exception exportEx)
{
try
{
ChangeStatus(MessageStatus.ERROR);
AddErrorDescription(exportEx.Message);
}
catch (Exception statusEx)
{
throw new MessageException("Couldn't export message and set its status to ERROR: " +
exportExt.Message + "; " + statusEx.Message, Type, Id, statusEx);
}
throw new MessageException("Couldn't export message, exception: " + exportEx.Message, Type, Id, exportEx);
}
}
private void ChangeStatus(MessageStatus status)
{
try
{
Status = status;
srcDb.UpdateDataSet(drHeader.Table.DataSet, HEADERS,
CreateHeaderInsertCommand(), CreateHeaderUpdateCommand(), null);
}
catch (Exception statusEx)
{
throw new MessageException("Failed to change message status to " + status + ":" + statusEx.Message, statusEx);
}
}