How to deal with TransactionScope during debugging? - asp.net

I have WebService that is hosted by ASP.NET web site. Inside the TransactionScope object is used to handle transactions:
using (TransactionScope scope = new TransactionScope())
{
...
scope.Complete();
}
The problem is that during debugging, when I am going through each line in step-by-step mode,
transaction timeout is occurred and any attempt to access DB crashed with '' error, and as a result: further debugging is prohibited.
How could I handle that without deleting mentioned lines of code?
P.S. I've tried to find, how to increase a time-out of created transaction, but didn't find something helpful.
Any thoughts are welcome.
Thanks.

You can specify an infinite timeout for the Transaction by passing in a zero length TimeSpan as part of the constructor:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0)))
The TransactionScopeOption of Required is what is used as default with your parameterless constructor.
See http://msdn.microsoft.com/en-us/library/ms172152(VS.90).aspx for more information.

Related

The configured execution strategy 'SqlRetryingExecutionStrategy' does not support user-initiated transactions

I have ASP.Net 4.7.2 window service which is processing NServiceBus messages. Currently it is deployed to On-Premise server. It has retry mechanism as well and working fine. Now I am going to containerizing it. While running into docker window container, it is doing SQL operation using Entity framework and giving exception as mentioned below:
The configured execution strategy 'SqlRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit.
While running locally by installing manually or on On-Premise server, it is working fine but in container it is throwing exception.
Can any one help me what can be the root cause?
It sounds like the piece of code does manual transaction management and is not wrapped within an execution strategy execute.
if your code initiates a transaction using BeginTransaction() you are defining your own group of operations that need to be treated as a unit, and everything inside the transaction would need to be played back shall a failure occur.
The solution is to manually invoke the execution strategy with a delegate representing everything that needs to be executed. If a transient failure occurs, the execution strategy will invoke the delegate again.
https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency#execution-strategies-and-transactions
using var db = new SomeContext();
var strategy = db.Database.CreateExecutionStrategy();
strategy.Execute(
() =>
{
using var context = new SomeContext();
using var transaction = context.Database.BeginTransaction();
context.SaveChanges();
transaction.Commit();
});
``

Using Simple Injector with Background worker in WinForms to Save to DB using EF6

I've been given an old WinForms app to update and improve. I am trying to add DI using SimpleInjector. I'm used to .Net MVC but this is my first time working with WinForms.
The application uses a lot of BackGround workers. My understanding is that this is specific to WinForms and each Background worker creates a new thread.
I think my problem is that when I want to save data to the DB using EF6 the SaveChanges method isn't able to save because of the multiple threads.
My SimpleInjector container is set up as follows
_container = new Container();
_container.Options.DefaultScopedLifestyle = new ThreadScopedLifestyle();
// Register DbContext
_container.Register<DbContext, MyDbContext>(Lifestyle.Scoped);
When I call SaveChanges on my dbContext I get a result of 0, which indicates that no records were saved to the database. In my debugger I get an error saying that the DbContext has been disposed. If this is happening before the save it explains why a 0 is returned from SaveChanges. Unfortunately the previous developer caught every exception so the application is trying to handle every error and this is making troubleshooting difficult and leading to unexpected behavior.
I am expecting a new DbContext to be created for each thread and that SaveChanges will save the changes made in each thread, so that what happens in one context won't affect other DbContexts in other threads.
When I am reading from the database I manually create a new DbContext in each method. Is it possible that when the using block has completed it is disposing the DbContext ?
using (var newDbContext = new MyDbContext())
{
return newDbContext.Set<TableA>().First(x => x.Id == id);
}
I'm hoping that if I have SimpleInjector configured correctly I won't need to do this either.
I'm a little lost at this stage and think I might not be understanding the documentation correctly, any advise would be greatly appreciated. Thanks in advance.
I am expecting a new DbContext to be created for each thread
This is not how TheadScopedLifestyle works. With the ThreadScopedLifestyle, there will be one instance of your registration within the context of an explicitly started Scope and this scope is thread-specific. This means that one thread can have many instances of that service, since a thread can live for a long time, while a Scope will typically only live for a short amount of time.
A typical use for ThreadScopedLifestyle is the following:
void MethodThatRunsInABackGroundThread()
{
using (ThreadScopedLifestyle.BeginScope(container))
{
var service = container.GetInstance<ISomeService>();
service.DoWork();
}
}
When you resolve Scoped instances (or some object graph that contains scoped instances) outside an active scope, Simple Injector will throw an exception.

SQLite.NET PCL Busy Exception

We are using the SQLite.NET PCL in a Xamarin application.
When putting the database under pressure by doing inserts into multiple tables we are seeing BUSY exceptions being thrown.
Can anyone explain what the difference is between BUSY and LOCKED? And what causes the database to be BUSY?
Our code uses a single connection to the database created using the following code:
var connectionString = new SQLiteConnectionString(GetDefaultConnectionString(),
_databaseConfiguration.StoreTimeAsTicks);
var connectionWithLock = new SQLiteConnectionWithLock(new SQLitePlatformAndroid(), connectionString);
return new SQLiteAsyncConnection (() => { return connectionWithLock; });
So our problem turned out to be that although we had ensured within the class we'd written that it only created a single connection to the database we hadn't ensured that this class was a singleton, therefore we were still creating multiple connections to the database. Once we ensured it was a singleton then the busy errors stopped
What I've take from this is:
Locked means you have multiple threads trying to access the database, the code is inherently not thread safe.
Busy means you have a thread waiting on another thread to complete, your code is thread safe but you are seeing contention in using the database.
...current operation cannot proceed because the required resources are locked...
I am assuming that you are using async-style inserts and are on different threads and thus an insert is timing out waiting for the lock of a different insert to complete. You can use synchronous inserts to avoid this condition. I personally avoid this, when needed, by creating a FIFO queue and consuming that queue synchronously on a dedicated thread. You could also handle the condition by retrying your transaction X number of times before letting the Exception ripple up.
SQLiteBusyException is a special exception that is thrown whenever SQLite returns SQLITE_BUSY or SQLITE_IOERR_BLOCKED error code. These codes mean that the current operation cannot proceed because the required resources are locked.
When a timeout is set via SQLiteConnection.setBusyTimeout(long), SQLite will attempt to get the lock during the specified timeout before returning this error.
Ref: http://www.sqlite.org/lockingv3.html
Ref: http://sqlite.org/capi3ref.html#sqlite3_busy_timeout
I have applied the following solution which works in my case(mobile app).
Use sqlitepclraw.bundle_green nugget package with SqlitePCL.
Try to use the single connection throughout the app.
After creating the SQLiteConnection.
Apply busytime out using following call.
var connection = new SQLiteConnection(databasePath: path);
SQLite3.BusyTimeout(connection.Handle, 5000); // 5000 millisecond.

How to prevent a service from stopping on Error

I wrote a Windows Service that polls data on some timeintervalls and writes them in database.
But if there occures an Error writing to Database and the service stops.
I want a robust solution that goes on even if an error occures.
I put try/catch bocks around every action that is done by the service in OnStart, OnStop and Dispose but it sopped anyway.
is try/catch the correct approach?
And where do I have to put it?
Will it help to put try/catch in Main method?
Many thanks.
Try wrapping your call in a TransactionScope, this will roll back any failed changes you are trying to make and should not break on failure.
using (var scope = new TransactionScope())
{
DeleteStuff();
UpdateStuff();
scope.Complete();
}

Application_Start timeout?

I have one piece of code that gets run on Application_Start for seeding demo data into my database, but I'm getting an exception saying:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
While trying to enumerate one of my entities DB.ENTITY.SELECT(x => x.Id == value);
I've checked my code and I'm not disposing my context before my operation, Below is an outline of my current implementation:
protected void Application_Start()
{
SeedDemoData();
}
public static void SeedDemoData()
{
using(var context = new DBContext())
{
// my code is run here.
}
}
So I was wondering if Application_Start is timing out and forcing my db context to close its connection before it completes.
Note: I know the code because I'm using it on a different place and it is unit tested and over there it works without any issues.
Any ideas of what could be the issue here? or what I'm missing?
After a few hours investigating the issue I found that it is being caused by the data context having pending changes on a different thread. Our current implementation for database upgrades/migrations runs on a parallel thread to our App_Start method so I noticed that the entity I'm trying enumerate is being altered at the same time, even that they are being run on different data contexts EF is noticing that something is wrong while accessing the entity and returning an incorrect error message saying that the datacontext is disposed while the actual exception is that the entity state is modified but not saved.
The actual solution for my issue was to move all the seed data functions to the database upgrades/migrations scripts so that the entities are only modified on one place at the time.

Resources