This is my coding. It shows error like
An error occurred while starting a transaction on the provider connection. See the inner exception for details.
DemoEntities db = DemoEntities.CreateNewDemoEntity();
var query = (from f in db.Product_Table
where f.ReportID == reportID && f.StateID == stateID
select f);
foreach(var q in query)
{
Custom_Search_Transformation cst = new Custom_Search_Transformation()
{
CustomerID = customerID,
StateID = stateID,
FullProductID = q.FullProductID
};
db.Custom_Search_Transformation.AddObject(cst);
db.SaveChanges();
}
asked Jan 23, 2014 at 11:07
3
Make your Queryable lists to .ToList() it should work fine.
answered Apr 15, 2015 at 20:46
zazazaza
3652 silver badges7 bronze badges
2
The db.SaveChanges();
should come outside of the foreach
loop:
DemoEntities db = DemoEntities.CreateNewDemoEntity();
var query = (from f in db.Product_Table
where f.ReportID == reportID && f.StateID == stateID
select f);
foreach(var q in query)
{
Custom_Search_Transformation cst = new Custom_Search_Transformation()
{
CustomerID = customerID,
StateID = stateID,
FullProductID = q.FullProductID
};
db.Custom_Search_Transformation.AddObject(cst);
}
db.SaveChanges();
answered Jan 23, 2014 at 11:14
GoldaGolda
3,79510 gold badges34 silver badges65 bronze badges
1
Manstrike 0 / 0 / 0 Регистрация: 21.12.2016 Сообщений: 3 |
||||
1 |
||||
.NET 4.x 21.12.2016, 20:46. Показов 5886. Ответов 3 Метки entity-framework-code-first (Все метки)
Собственно, есть некая форма, на которой содержаться данные, по нажатию кнопки создается новый объект в таблице Cart, значения берутся правильно, но при выполнении выскакивает исключение «An error occurred while starting a transaction on the provider connection. See the inner exception for details.» Подозреваю, что я неправильно организовал связи между таблицами.
__________________
0 |
Администратор 15248 / 12287 / 4904 Регистрация: 17.03.2014 Сообщений: 24,883 Записей в блоге: 1 |
|
21.12.2016, 21:44 |
2 |
Manstrike, как сказано в ошибке — «See the inner exception for details» — т.е. точная причина описана во вложенном исключении.
0 |
0 / 0 / 0 Регистрация: 21.12.2016 Сообщений: 3 |
|
21.12.2016, 21:53 [ТС] |
3 |
посмотрел во вложенное исключение и увидел следующую ошибку «Новая транзакция не допускается, так как в данном сеансе запущены другие потоки.»
0 |
Администратор 15248 / 12287 / 4904 Регистрация: 17.03.2014 Сообщений: 24,883 Записей в блоге: 1 |
|
21.12.2016, 22:27 |
4 |
Сообщение было отмечено Manstrike как решение РешениеManstrike, попробуйте вызвать SaveChanges() после цикла.
1 |
- Remove From My Forums
-
Question
-
Hi
I am getting this error intermittently, the exception details are as follows:
Exception classes:
System.Data.SqlClient.SqlException
System.Data.EntityExceptionException messages:
New transaction is not allowed because there are other threads running in the session.
An error occurred while starting a transaction on the provider connection. See the inner exception for details.Stack Traces:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject
stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName)
at System.Data.SqlClient.SqlInternalConnection.BeginTransaction(IsolationLevel iso)
at System.Data.SqlClient.SqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
— Next Call Stack:
at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Objects.ObjectContext.SaveChanges(Boolean acceptChangesDuringSave)The code snippet that causes this exception is as follows:
public void AddThirdPartyForApplication(List<int> Applications, int ThirdPartyUserId) {
try
{
if (Applications.Count <= 0 || ThirdPartyUserId <= 0)
return;foreach (int ApplicationId in Applications)
{ var tpts = from pt in MyDB.ApplicationThirdParty
where pt.OrganizationUser.User_Id == ThirdPartyUserId && pt.Application.Application_Id == ApplicationId
select pt;ApplicationThirdParty thirdP = tpts.FirstOrDefault<ApplicationThirdParty>();
if (thirdP == null) //does not exists
{ ApplicationThirdParty newThirdP = new ApplicationThirdParty();
newThirdP.Application = MyDB.Proposal.Where(p => p.Application_Id == ApplicationId).FirstOrDefault();
newThirdP.OrganizationUser = MyDB.OrganizationUser.Where(o => o.User_Id == ThirdPartyUserId).FirstOrDefault();
newThirdP.Is_Active = true;
MyDB.AddToApplicationThirdParty(newThirdP);
}
else
thirdP.Is_Active = true;}
MyDB.SaveChanges();
}
catch (Exception ex)
{
ExceptionLogger.LogException(ex); throw new DataAccessException(ex.Message, «AddThirdPartyForApplication»);
}
}
I am seeing this error randomly in one of our environments…Not sure how this can happen. Looks like the connection is disposed after EF ensures that the connection is good(in SaveChanges). Any thoughts?
System.Data.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. —> System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at SNINativeMethodWrapper.SNIPacketReset(SafeHandle pConn, IOType ioType, SafeHandle packet)
at System.Data.SqlClient.TdsParserStateObject.WriteSni()
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction,
TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName)
at System.Data.SqlClient.SqlInternalConnection.BeginTransaction(IsolationLevel iso)
at System.Data.SqlClient.SqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
— End of inner exception stack trace —
at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Objects.ObjectContext.SaveChanges(Boolean acceptChangesDuringSave)
Thanks,
Bek
Reproduce MySQL «nested transactions» exception
This example project shows how to reproduce an exception regarding «nested transactions» in a simple .NET Web API + Entity Framework 6 + MySQL project.
Update: the cause of the issue is this bug in MySQL .NET connector: http://bugs.mysql.com/bug.php?id=71502. It can be reproduced without Entity Framework / Web API.
Description
The project uses .NET Web API, Entity Framework 6 with code-first migrations and the MySQL Entity Framework connector. It contains a single entity Author
with a column Name
which has a unique constraint.
When repeatedly inserting an entity with the same value for Name
, I would expect to get an exception that the unique constraint is violated every time. However in my experience every second attempt a MySqlException with message «Nested transactions are not supported.» is thrown.
Prerequisites
- Microsoft Visual Studio 2013 (tested on Community edition)
- A MySQL server. Tested on:
- 5.6.23-log Community / Win64 (local machine)
- 5.6.22-log Community / Linux (x86_64) (Amazon RDS micro instance)
Instructions
Clone and build
- Clone the repository in a new folder.
- Open the solution in Visual Studio 2013.
- Build. VS will download the missing NuGet packages on first build.
Prepare database
- Create a database and user on your MySQL server.
- Adapt
Web.config
for your MySQL connection string, here:
<connectionStrings> <add name="ReproduceMySqlNestedTransactionExceptionContext" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=reproduce_nested_transactions_error;uid=reproduce_user;password=test1234" /> </connectionStrings>
- In the Package Manager Console of Visual Studio, run
Update-Database
. The database structure will be created from the migrations.
Run
Run the test «PostSameAuthor» from the Test Explorer. This test repeatedly calls Post()
with an Author
with the same name, and expects an exception with message «Duplicate entry» from the second call onwards.
Output
The test fails. The 2nd call gives the expected result, but at the 3rd call a MySqlException
with message «Nested transactions are not supported.» is thrown.
Details of the exception can be seen by debugging the test instead of running it (Test Explorer -> Debug Selected Tests). Stack trace below.
System.Data.Entity.Core.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. ---> System.InvalidOperationException: Nested transactions are not supported.
at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex)
at MySql.Data.MySqlClient.MySqlConnection.BeginTransaction(IsolationLevel iso)
at MySql.Data.MySqlClient.MySqlConnection.BeginTransaction()
at MySql.Data.MySqlClient.MySqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.Common.DbConnection.BeginTransaction(IsolationLevel isolationLevel)
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.<BeginTransaction>b__0(DbConnection t, BeginTransactionInterceptionContext c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.BeginTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.EntityConnection.<>c__DisplayClassf.<BeginDbTransaction>b__d()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
--- End of inner exception stack trace ---
at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.Common.DbConnection.BeginTransaction()
at System.Data.Entity.Core.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at ReproduceMySqlNestedTransactionException.Controllers.AuthorsController.PostAuthor(Author author) in ReproduceMysqlNestedTransactionExceptionReproduceMySqlNestedTransactionExceptionControllersAuthorsController.cs:line 29
at ReproduceMySqlNestedTransactionException.Controllers.AuthorsControllerTests.PostAndExpectDuplicateException(AuthorsController authorCon, Author author, Int32 callNumber) in ReproduceMysqlNestedTransactionExceptionReproduceMySqlNestedTransactionExceptionControllersAuthorsControllerTests.cs:line 53
Home
> LightSwitch > LightSwitch: Oracle An error occurred while starting a transaction on the provider connection. See the inner exception for details
I got this issue today while connecting to the Oracle database. I am not taking credit of the solution but I couldn’t find a post that explains it step by step. For the benefit of the community I decided to write this post. It is also good for me to find the solution later on if I get stuck J
To fix the issue we need to create a transaction scope and call TransactionScope.complete when the execution is complete
Right click the oracle Datasource
Select View Code
Add the following code to the generated class; replace OracleDSService with the name of your class
using System.Transactions; namespace LightSwitchApplication { public partial class OracleDSService { private TransactionScope transactionScope; partial void SaveChanges_Executing() { transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }); } partial void SaveChanges_Executed() { transactionScope.Complete(); } } }
In my case System.Transactions namespace wasn’t resolved. To fix that I had to add a reference to the System.Transactions assembly
To do so, follow these steps
Switch to the File View
Right click on the server project and choose Add Reference
Find the System.Transactions assembly; in my case it was at C:WindowsMicrosoft.NETFrameworkv4.0.30319System.Transactions.dll
Save the solution, build, and run
В моей службе у меня есть фоновый поток, который лучше всего экономит поток потока объекта определенного типа. Код выглядит примерно следующим:
while (AllowRun)
{
try
{
using (DbContext context = GetNewDbContext())
{
while (AllowRun && context.GetConnection().State == ConnectionState.Open)
{
TEntity entity = null;
try
{
while (pendingLogs.Count > 0)
{
lock (pendingLogs)
{
entity = null;
if (pendingLogs.Count > 0)
{
entity = pendingLogs[0];
pendingLogs.RemoveAt(0);
}
}
if (entity != null)
{
context.Entities.Add(entity);
}
}
context.SaveChanges();
}
catch (Exception e)
{
// (1)
// Log exception and continue execution
}
}
}
}
catch (Exception e)
{
// Log context initialization failure and continue execution
}
}
(это в основном фактический код, я пропустил несколько не относящихся к делу частей, которые пытаются сохранить всплывающие объекты в памяти, пока мы не сможем снова сохранить материал в БД, когда исключение попадает в блок (1)
)
Итак, по сути, существует бесконечный цикл, который пытается прочитать элементы из некоторого списка и сохранить их в Db. Если мы обнаружим, что соединение с БД не удалось по какой-то причине, оно просто пытается открыть его и продолжить. Проблема в том, что иногда (я не смог понять, как ее воспроизвести до сих пор), код выше при вызове context.SaveChanges()
начинает вызывать следующее исключение (попадание в блок (1)
):
System.Data.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. --->
System.InvalidOperationException: The requested operation cannot be completed because the connection has been broken.
Ошибка регистрируется, но когда выполнение возвращается к тегу context.GetConnection().State == ConnectionState.Open
, оно принимает значение true. Таким образом, мы находимся в состоянии, когда контекст сообщает, что его соединение с БД открыто, но мы не можем запускать запросы в этом контексте. Перезапуск службы устраняет проблему (а также возится с переменной AllowRun
в отладчике для принудительного восстановления контекста). Поэтому вопрос заключается в том, что я не могу доверять состоянию контекстного подключения, как я могу проверить, что я могу запускать запросы к БД?
Кроме того, есть ли чистый способ выяснить, что соединение не находится в «здоровом» состоянии? Я имею в виду, что EntityException
сам по себе не является признаком того, что я должен reset соединение, только если его InnerException является InvalidOperationException
с определенным сообщением, то да, пришло время reset его. Но теперь я думаю, что были бы другие ситуации, когда ConnectionState указывает, что все в порядке, но я не могу запросить DB. Могу ли я поймать их проактивно, не дожидаясь, пока он меня не укусит?