Во-первых, в большинстве реляционных баз данных операции чтения и записи для объектов базы данных всегда будут выполняться внутри транзакции. Даже если вы не запускаете транзакцию явно, она будет запущена неявно. Это должно как минимум ответить на вопрос, имеет ли смысл использовать транзакции для операторов чтения - в большинстве случаев вы все равно получите транзакцию. Примером случая, когда транзакции не создаются неявно, является запрос типа SELECT 2 * 3
, который не включает объекты базы данных.
Когда мы говорим о транзакциях, мы также должны говорить об уровнях изоляции. Транзакции имеют значение для операторов чтения , так же, как и для всех других видов операций с базой данных. Уровень изоляции управляет тем, какие данные состояния согласованности считываются и устанавливаются ли блокировки чтения. В вашем примере уровень изоляции транзакции установлен на READ COMMITTED
, что можно было сделать специально. Представьте, что для вашей базы данных по умолчанию установлен уровень транзакции READ UNCOMMITTED
- использование неверного уровня изоляции может привести к нежелательным побочным эффектам, в зависимости от того, чего вы пытаетесь достичь с помощью этого запроса.
Я бы не стал удалять транзакцию объем, только потому, что это операция чтения. Сначала вы должны выяснить, как настроена ваша база данных и как данные записываются в таблицу, из которой вы читаете.
Относительно утечки памяти: ваша область видимости, по-видимому, правильно настроена, поэтому я не понимаю, почему Само объявление области может привести к утечке памяти. Это также может быть ошибка в используемой версии драйвера базы данных. Скорее всего, этот метод вызывается очень часто, создавая таким образом множество объектов, связанных с транзакциями.
Мне невозможно сказать, каков правильный подход, поскольку я недостаточно знаю о вашем приложении и о том, как метод называется. Тем не менее, вот несколько вещей, которые вы могли бы рассмотреть:
1) Используйте Required
вместо RequiresNew
. Один из методов в иерархии вызовов уже может иметь объявленную область транзакции. Если вы создадите вложенную область транзакции, используя RequiresNew
, как это происходит в вашем случае, она не будет повторно использовать эту существующую транзакцию, а вместо этого создаст новую. Изменение параметра области действия на Required
приведет к повторному использованию транзакции из родительской области или к созданию новой, если родительская область отсутствует.
2) Можно попытаться переместить объявление области несколько уровни в иерархии вызовов. TransactionScope
является окружающим, поэтому область транзакции «наследуется» при последующих вызовах методов. Таким образом, вы можете уменьшить количество создаваемых объектов.