2015-09-22 7 views
4

Я пытаюсь использовать Entity Framework 6 с SQLite и работать с проблемой блокировки базы данных при попытке использовать TransactionScope. Вот мой код:База данных TransactionScope и SQLite заблокирована

using (var txn = new TransactionScope()) 
{ 
    using (var ctx = new CalibreContext()) 
    { 
     var book = ctx.Books.First(x => x.Id == 2); 
     var author = ctx.Authors.First(x => x.Id == 3); 
     book.Authors.Add(author); 
     ctx.SaveChanges(); 
    } 
    txn.Complete(); 
} 

Первая линия var book = ctx.Books.First(x => x.Id == 2); выполняет ОК. но затем, как только я перехожу к следующему, я получаю исключение, говоря, что моя база данных заблокирована. Вот мое приложение конфигурации:

<configuration> 
    <configSections> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" /> 
    </startup> 
    <connectionStrings> 
    <add name="CalibreContext" connectionString="Data Source=metadata.db" providerName="System.Data.SQLite.EF6" /> 
    </connectionStrings> 
    <system.data> 
    <DbProviderFactories> 
     <remove invariant="System.Data.SQLite" /> 
     <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.98.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> 
     <remove invariant="System.Data.SQLite.EF6" /> 
     <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".Net Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6, Version=1.0.98.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> 
    </DbProviderFactories> 
    </system.data> 
    <entityFramework> 
    <defaultConnectionFactory type="Calibre.Dal.Ef.SQLiteConnectionFactory, Calibre.Dal.Ef" /> 
    <providers> 
     <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6, Version=1.0.98.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> 
     <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6, Version=1.0.98.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> 
    </providers> 
    </entityFramework> 
</configuration> 

мне нужно использовать TransactionScope, потому что в дополнение к выполнению операции DB, я также должен выполнить операцию файловой системы, который я планирую на добавление к одной и той же сделки (в настоящее время не существует) ,

ответ

4

У меня возникла аналогичная проблема. Чтобы быть ясным, ошибка, которую я получил во втором запросе, заключалась в том, что «основной поставщик отказался от Open» (но причиной отказа Open было то, что база данных была заблокирована).

Видимо проблема связана с MSDTC (TransactionScope тесно связана с MSDTC).

a community addition to an MSDN page Я нашел что, в свою очередь, ссылается на this blog post
... в котором говорится, что операции «повышен» до MSDTC сделок, если соединение закрывается и снова открывается. Какой EF делает по умолчанию. Обычно это хорошо - вы не хотите, чтобы ручки базы данных висели навсегда, но в этом случае это мешает.

Решение явно открыть соединение с базой данных:

using (var txn = new TransactionScope()) 
{ 
    using (var ctx = new CalibreContext()) 
    { 
     ctx.Connection.Open(); 
     // ... remainder as before ... 

В качестве альтернативы, если все ваши CalibreContext объекты недолговечны, вы, вероятно, может открыть соединение в CalibreContext конструктора.

Это, похоже, устранило мою проблему. Я опубликую обновление, если у меня есть что-нибудь еще, чтобы сообщить.

Смежные вопросы