#c# #sql #transactions
#c# #sql #транзакции
Вопрос:
Я выполняю некоторую операцию вставки в SQL server в TransactionScope.
Вот мой код
using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
Int32 existingDBRowCount = GetTableRowCount(currentTableName);
//... Code to Insert Data into Table
Int32 newDBRowCount = GetTableRowCount(currentTableName);
// New Row Count should be equal to Existing DB Row Count Rows to be inserted
if (newDBRowCount != (existingDBRowCount toBeInsertedRowCount))
Transaction.Current.Rollback();
else
scope.Complete(); // Commit the Transaction
}
public Int32 GetTableRowCount(string tableName)
{
using (SqlConnection sqlConnection = GetSQLConnection())
{
if (sqlConnection.State != ConnectionState.Open)
sqlConnection.Open();
string queryString = "SELECT COUNT(*) FROM [" tableName "]";
using (var sqlCommand = new SqlCommand())
{
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandType = CommandType.Text;
sqlCommand.CommandText = queryString;
var rowCount = (int) sqlCommand.ExecuteScalar();
return rowCount;
}
}
}
По сути, что я делаю, так это отслеживаю количество строк в таблице, а затем после вставки новых данных проверяю, соответствует ли количество новых строк = существующим строкам количество строк, которые нужно вставить
Если оба совпадают, я фиксирую транзакцию, в противном случае выполняю откат
У меня есть два вопроса:
1) Правильно ли это определение?
2) В некоторых случаях количество строк новой базы данных совпадает с количеством существующих строк, я предположил, что это потому, что моя транзакция не была зафиксирована до этого момента, но это очень случайно, в основном она возвращает правильное количество строк. Я не могу понять, что происходит не так
Комментарии:
1. Нет, этот подход неверен. Все зависит от вашей логики, которая выполняется внутри транзакции. Но вы должны быть в состоянии достичь любого необходимого вам уровня синхронизации, используя уровни изоляции транзакций. Они могут помешать другим транзакциям вставлять строки в диапазон, который заблокирован вашей транзакцией. Подробнее читайте на msdn.microsoft.com/en-us//library/ms173763.aspx . Но не будьте слишком строгими — это снизит производительность. Выберите минимальный уровень столбца, который обеспечит согласованность вашей логики
Ответ №1:
Если вам нужно правильное количество строк даже без фиксации данных, вам необходимо установить IsolationLevel.ReadUncommitted при чтении количества строк таблицы
SqlTransaction transaction = SqlConnection.BeginTransaction(IsolationLevel.ReadUncommitted);
а затем назначить эту транзакцию вашей команде SQL
Смотрите эту ссылку http://msdn.microsoft.com/en-us/library/5ha4240h (v = против 110).aspx