Sql Server Compact Edition concurrency / thread safety (i.e. not thread safe) - c#

Over the last few months I have been developing an application using Entity Framework code first and sql server CE for the first time. I have found the combination of the 2 very useful, and compared to my old way of doing things (particularly ADO.NET) it allows for insanely faster dev times.
However, this morning me and some colleagues came across a problem which we have never seen in any documentation regarding SqlServer CE. It cannot handle more than one insert at once!
I was of the opinion that CE may become my database of choice until I came across this problem. The reason I discovered this was in my application I needed to make multiple requests to a web service at once, and it was introducing a bit of a bottleneck so I proceeded to use a Parallel.Invoke call to make the multiple requests.
This was all working fine untill I turned on my applications message logging service. At this point I began to get the following error when making the web requests:
A duplicate value cannot be inserted into a unique index. [ Table name = Accounts,Constraint name = PK__Accounts__0000000000000016 ]
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlServerCe.SqlCeException: A duplicate value cannot be inserted into a unique index. [ Table name = Accounts,Constraint name = PK__Accounts__0000000000000016 ]
Strange I thought. And my first recation was that it must be something to do with the DbContext, maybe the DbContext I was using was static or something else in my Repository class was static and causing the problem, but after sniffing around I was certaing it was nothing to do with my code.
I then brought it to the attention of my colleagues and after a while it was decided it must be SqlServer CE, and after us all setting up different test projects attempting to recreate the problem using threads it was recreated almost every time, and when using Sql Server Express the problem wasn't ocurring.
I just think it is a bit strange that CE cannot handle something as simple as this. I mean the problem is not only with threading - are you telling me that it cannot be used for a web application where two users may insert into a table at the same time...INSANITY!
Anyway, just wondering if anyone else has come across this late into a project like me and been shocked (and annoyed) that it works this way? Also if anyone could shed light on why it is limited in this way that would be cool.

It looks like a bug in SQL CE. See http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=641518

Related

How to set numeric round abort in Entity Framework

I am working on enhancing an application and using Microsoft .NET Core Identity for IAM in our application [Microsoft.AspNetCore.Identity.EntityFrameworkCore].
The database is Microsoft SQL Server. The database setup is pretty much standard except the "NUMERIC_ROUNDABORT" will be turned ON.
But when we start the application we are getting the below exception.
System.Data.SqlClient.SqlException:
'CREATE INDEX failed because the following SET options have incorrect settings: 'NUMERIC_ROUNDABORT'.
Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type
Working scenarios :
Scenario 1: When the "NUMERIC_ROUNDABORT" is turned OFF in server level, the application works fine and no issues.
Scenario 2: When I extract the table creation queries from the database and execute them with "NUMERIC_ROUNDABORT" turned ON, still everything works.
Scenario 3: When the "NUMERIC_ROUNDABORT" is turned OFF in server level, and started application first time (letting all the tables created by ef core) and turned ON, next time onwards app works, as the necessary tables and indexes are created already.
Non-working scenario :
When the "NUMERIC_ROUNDABORT" is turned ON in server level, and when we run the application first time, it throws an exception.
I understand the reason that it is expected to get the exception after a loss of precision occurs in an expression and when creating or changing indexes on computed columns or indexed views.
Could you please help me, can we fix this programmatically. Is that possible?
P.S: Changing in the database will not be a possible option[In my case].
Thank you all for your advice and help.

remote access is not supported for transaction isolation level snapshot - is this conditional?

Folks - apologies for rehashing this topic as I see even here on Stack, there are so many questions on the topic already.
But I find myself in an interesting place and I'm hoping you can help.
High level Question: can SQL SERVER have the leeway to decide that a view should be wrapped in a ISOLATION LEVEL SNAPSHOT?
I know that sounds like a crazy question but I'm trying to exhaust all avenues per an issue I'm encountering.
I'm working with an application that runs 35 queries to retrieve data from another database via Link Server. The queries are simple selects against one table respectively. All DB operations are carried out against SQL SERVER, and retrieval code is ADO.NET/c#, etc.
34 of the queries work flawlessly - but there's this one bad apple, and for it, I get the transaction isolation level snapshot issue.
I've also tested data retrieval outside of the application and when I implement the below snippet on the "problem" query, I also get the issue:
using (var trans = conn.BeginTransaction(IsolationLevel.Snapshot))
However, when I do NOT implement it on said query, all is well.
I've also tested this against the other queries - with and without "Shapshot" - and my results are predictable... With "Shapshot" in place, no queries process... When not implemented, all queries process...
My results suggest that the application is responsible for changing up the data retrieval strategy.
Per their knowledge base, I found this: Locking is handled by the database level (MS SQL Server/Oracle) and not by "us". Generally, locking is row level but the optimizer may choose something different
Unfortunately I don't have native access to the boiler-plate application code responsible for data retrieval. I suspect that this particular query/table has one or more key words - either in the column or query/table naming - that trigger the application to use an alternate retrieval strategy. Per the developer forums, I've asked of this is the case and I'm awaiting a reply...
Anyway back to their mention of the optimizer may choose something different- their optimizer, or perhaps the database optimizer? Can SQL SERVER be set up to make a "judgement call" ? Is the statement unclear or do I just not enough of SQL SERVER and its capabilities?
I know it seems like a crazy question but I really want to knock out all possible avenues here.
Thank you kindly for suspending your disbelieve and humoring that crazy post :)
Apparently objects with the word "valuation" (perhaps because of the sensitive nature implied) cause the application to build the transaction. Once I changed the view name, the data returned to the client successfully.
So yes the application was/is the issue.

Abstraction of SqlExceptions (using Entity Framework)

I have been using Entity Framework 6 and trying to handle some common problems like Primary/Foreign/Unique Key constraints via EF. EF gives SqlException as an InnerException and it seems that - as far as I found upto now - the only way to understand the actual problem is using error codes in that SqlException object?
I would like to abstract these exceptions by catching EF exceptions and throwing my own exceptions by analyzing the error code in the InnerException. I have some considerations at that point.
SQL Server codes change by the server version or not? Should I handle
different versions of SQL Server in a different way like creating different implementations for 2008, 2012 and etc?
Instead of SQL Server it is possible to use other SQL Servers like
MySQL and its another reason I am trying to abstract these
exceptions.
For example, as in the accepted answer of that question, I would like catch specific errors, but instead of rethrowing I would like to throw my own exception(s). If I do not want to do something special or I do not have any special exception for the error I can create and use a more generic exception in which I can store the original exception into that generic exceptions InnerException field.
I read this blog post and unfortunately the problematic case was my first way to go. I would like to do that without using any third party library as much as possible (of course this is not more important doing it right). I wonder if there is tested and accepted way of doing this, otherwise I am open to any suggestion.
SQL Server codes change by the server version or not?
Exception numbers cannot change once released. Deadlock is and will remain 1205, unique index duplicate key is and will remain 2601, unique constraint violation is and will remain 2627 and so on and so forth. But, you see, in the very examples I choose I show you the danger lurking in relying on these: what decides the difference between 2601 and 2627? Your friendly DBA can decide that it should drop an unique index and instead add an unique constraint (enforce by an index, but that is irrelevant) and all of the sudden your app sees new errors. By doing deep inspection of the exception you add coupling between the application code and the SQL storage, and risk breaking the app when the storage modifies in what would otherwise be a completely transparent change (eg. add an index). Be warned.
I think is feasible to add handling for several well known cases. But you must allow for generic exception you are not aware of ad development time, and handle those.
As for cross-platform, you would have to customize for each platform. The good news is that a 'primary key violation' is the same concept on SQL Server and on MySQL, so you could translate it to a PrimaryKeyViolationException for both providers. Is not trivial, but it is possible.
And finally, a heads up: I've seen folk trying to do similar before, to mix results. The benefits are not exactly overwhelming, and the effort put in is considerable.

ASP.NET with EF 4 getting incorrect data from SQL Server database

I updated my ASP.NET site from Linq-to-SQL to EF 4. I've had a bunch of hiccups along the way but have ironed most out.
Not sure if it has anything to do with EF but recently my application has started going nuts at random times. I'll delete one or multiple records from my SQL Server database, but when I re-display the page that was listing those records they're still there. I check my database and the records are gone yet when my code queries for this data after it's deleted my data model is still getting that deleted data and displaying it on my site. The only way I've found to get around the issue is closing the web browser or stopping my local host when debugging. Obviously not the fix I want. It happens on server code and local host.
This problem is very rare and difficult to reproduce and it only happens some days but not most days. I'd like to say it's completely random but I know there has to be some variable and I can't figure it out. Any suggestions?

SQL Server built-in Change Tracking vs Sync Framework's C#/VB libraries

I went into a problem where using the following code did not change the scope_id value in the replica key map and scope_info table of Sync Framework 2.1 elements in my database, on a restored database on Windows XP 32-bit / SQL Server Express 2008 (x86). It DOES work on my other client that is Windows 7 64-bit / SQL Server Express 2008 (x86) :
SqlSyncStoreRestore databaseRestore = new SqlSyncStoreRestore(clientConn);
databaseRestore.PerformPostRestoreFixup();
SUB QUESTION 1:
It does not work but does not throw any exception either, which makes it much harder to troubleshoot. It is executed from a small console application (target x86) I built on my x64 computer (using Visual Studio x86). I wonder if the 32/64 bit thing is the culprit. Any clue?? But then, this made me wonder:
SUB QUESTION 2:
"Is there an SQL query equivalent to using PerformPostRestoreFixup() of Sync Framework's C#?"
I am fairly new to Sync Framework and I do not yet entirely see the whole picture of synchronization of Microsoft SQL Server databases. It came to my attention that the SyncOrchestrator/SqlSyncProvider combo does not use built-in SQL Change Tracking stuff. Incredibly surprising to me! It now made me haunted by an even more tormenting question:
SUB QUESTION 3:
Is the built-in SQL Server Change Tracking and Sync Framework two totally independent platform on which to build our synchronization scheme? I hope I am using the right words in English. In other words, is each of them completely unaware of the other??
Thanks in advance for your help! I am soooo lost LOL!
Kind Regards,
Zyxy
Question 1 - have you tried enabling sync fx tracing?
the Platform Target under your VS Project Properties->Build Tab should match the platform of Sync Fx installed. e.g., x86 Platform Target should have Sync Fx x86
if there is a mismatch on the x86/x64 thing, it would normally raise a COM exception.
Question 2 - you can run SQL Profiler to see what the PerformPostRestoreFixup. But i'd stick with the Framework doing this as there's some sync metadata processing involved.
Question 3 - SQL Change Tracking is just Change Tracking. you still need a synchronization app to use it.
SQL CT tracks what has changed and allows you query what has changed. it's not a sync platform by itself.
you need a sync app to query it just like Sync Fx. or you can hand code your own SQL queries to query for changes.
Sync Fx older SQLCeClientSyncProvider/DBServerSyncProvider/Sync Agent (the one used in the Local Database Cache Project Item) can use SQL CT.
Update: reason why it did not change the value but did not throw an exception either? The following is most likely the explanation. It does not completely answer the question as to why scope_id does not get updated, but it certainly provide additonal hints:
The PerformPostRestoreFixup() apply to all scopes in a database. I had another (valid) scope defined in the database that was successfully change its scope_id value. However, my 2nd scope (the one I could not change the scope_id) is stored in another schema (not the default .dbo). I guess it just did not see the scope, or deemed it invalid and therefore did not bother notifying me. I tried to deprovision that 2nd scope and got the following error:
Cannot find a valid scope with the name 'syncScope' in table '[scope_info]'. Ensure that this scope exists and that it has a corresponding valid configuration in the configuration table '[scope_config]'.
So these two issues might have the same root cause.
The 2nd scope does exist and I can go look at that darn scope_id with a select statement. Now how could I tell whether the configuration is valid or not? Why would it suddenly becomes invalid after a successful restore? I think it narrows it down but not enough for me hehe ;-) I will keep posting my findings and solution in case someone ever give a damn LOL! Just kidding but one day whow knows who it might help (or confuse) depending on the mood of the day I guess ;-) Cheers!
Ok, thanks to JuneT pointing me to Sync Fx 2.1 SDK's documentation (here or I read it on another discussion thread?), I realise I had a property I did not try yet. Reading online that the Sync Fx 2.0 (and others?) had issues with non-dbo schemas and issues with multi-scope database, I thought I would give it a try. Simply adding the following C# line in my console app solved it!
databaseRestore.ObjectSchema = "syncSchemaName";
Many of JuneT has pointed me, eventually, to some good readings and therefore I'll mark that one as the answer. MANY THANKS!!

Categories

Resources