C#: How to graciously manage errors on the application DataBase? - c#

I have a C# application that uses a localhost DB (MySQL).
Now, when I create the executable I´m assuming that the receptor computer MUST have the exact DB with the the same name and tables, also, must have running WAMP or XAMPP.
If one of this conditions is not accomplished the program will crash horribly, with the errors of Windows/C#.
I could put exceptions for every case, but I´m fearful that I would hide other errors putting exceptions for everything!
With production software, how do you manage this? With exceptions? Writing a manual for the user? etc?

During bootstrapping, I recommend check to see if a DB Connection can be created (in my case, SQL Server), given the database connection string defined in an app.config. Initially, you should do some version checking on the database. If the database can't be found, attempt to create it. if i'ts out of date, attempt to upgrade it. If this process fails, then your database engine instance isn't installed or is unresponsive. For my application case, I exit the program, as there's nothing else to do if the DB can't be accessed.
Once past this point, I generally assume that the DB connection is active.

Related

There are no active servers. Background tasks will not be processed

I have a problem which I already looking at it for a few days and still have no solution.
I found this exception in my C# web app log.
[2015-12-03 13:56:06] [ERROR] [] [Error occurred during execution of
'Server Bootstrapper' component. Execution will be retried (attempt
120 of 2147483647) in 00:05:00 seconds.]
[System.Data.SqlClient.SqlException (0x80131904): Login failed for
user "A Network account".
It appears to me that it is using the network account to access the SQL database and because that network account is not granted access to the database, hence login failed and server cannot startup.
However, when I go to the Hangfire dashboard, I can see the recurring jobs, which seems to me that hangfire can access the database with the right account for retrieving the recurring jobs.
Also, in the IIS server, we already set the Identity to "ApplicationPoolIdentity" for the application pools. Hence, we should use the virtual account instead of the network account.
May I know anyone has the similar problem and have the solution. Really appreciate for your help!!
I ran into the same issue using Hangfire with SQL Server and EntityFramework Code First where EntityFramework was responsible for creating the database, so this suggestion is based purely off of that scenario.
If you are using EF Code First, your database isn't created until the context is created and accessed for the first time.
This means that at App Start your database might not exist. Hangfire won't create the database, it only creates the tables in an already existing database.
So what you might be seeing is:
No database exists.
Your app start's up and Hangfire tries to get itself running, the server process throws an error because EF hasn't created the DB.
The web application start finishes since the hangfire service crashing isn't fatal to the application.
Something in your web app calls into EntityFramework.
EF runs and creates the database (likely no hangfire tables at this point)
you access the hangfire dashboard, hangfire is now able to connect, and see the tables don't exist, so it creates them. (now you will see the tables in your db)
The dashboard can now see the database and show you the stats (likely 0 servers running) so it seems like everything is working.
The way I solved it was to make sure that even if the database is empty (not tables), it is at least created. This was hangfire can access it to install it's tables and start, and EF can access it, and create it's schema.
Also, (and this probably isn't it), GlobalConfiguration.Configuration.UseSqlServerStorage() should run first before other Hangfire startup configuration.
Hope that helps!
Steve
You should create background job server instance, see document here
In my case, the server name was too long and there was a SQL error saying it would be truncated. I was only able to see this error after starting it with Just My Code turned off in Visual Studio.
Moral of the story: Use a shorter name for the server and don't append your own unique-per-instance identifiers to it so it can't run into a truncate error. The column is an nvarchar(100).

Database level lock in Microsoft SQL Server : schema migrations

I have a distributed application with multiple processes on multiple servers connect to a SQL Server database.
I need to migrate the database schema in code during first startup, because upgrade deployment can be done with the user without database access (we use computer object database access).
Currently this is done by providing a sql file with statements and then a user with db access (but potentially without app access) would run this independently.
Because apps do not talk to each other (firewalls, different DCs etc.) I was thinking that i'd have to designate one server as 'master', all others as 'slaves' and then on the master the first process that'd start would obtain the mutex and do the schema migrations; all others could simply wait until they can see the schema is migrated.
However, this has a certain code smell to me.
I tried researching how Entity Framework handles this in code first migrations and seems they don't (e.g. if two processes start at exact same time they would both try to migrate schema).
Any other approaches?
You can change mode of database to single-user (other connections) will be refused. Make the changes and then change back multi-user mode.
EDIT:
There is trick, how to get "mutex". You can update/delete record(s). Until transaction is open, the exclusive lock is stil holded. Probably, if you delete 0 records (with table-lock hint) from every table in transaction, you probably achieve same behaviour as "global mutex" for the users of database. But I don't know what behaviour will be with schema changes.

Saving data into SQL using PHP (C#)

I'm working on program (written in C#) that would run on few computers at once (their amount will very likely change over time). I want to save some data into SQL everytime some event occurs (nothing too complex, just a bit of information).
I'm not really sure how to do this the best way. I have these two options, I can connect directly to the SQL database straight from the program and insert everything I need, but I find this rather unsafe because someone could you this in bad way and gain access to my SQL without my permissions.
So I came up with this idea, I will have certain PHP file on the server which will handle all the data (my program will open internal hidden web browser window with address of the PHP file and all needed variables (I will use GET over here) and then it will close and wait for another event to happen).
Is the second solution way too bad habit to do or is it reasonably okay? Or even better, is there any better, more clean, solution to this kind of problem?
(It's not any kind of spyware or anything like that, it's just doing kind of diagnostics on the computer and giving me results with user's knowledge..)
Each time any event occurs, I have to insert one line into the table and it includes computer's ID, time and the event information.
The address used could look somewhat like this http:\\server.com\handle.php?id=xxxxxxxx&time=xx-xx-xxxx-xx-xx-xx-xxx&data=something
Is your application running on a LAN or are you on the Internet?
If you can access your SQL Server directly from your application on the default SQL Port (1433) what kind of security issues do you see?
If you run your application in a certain security context, you can connect to your SQL server using Windows security -> no username and password is sent.
BR
Frank

Issue with Microsoft Access

We have 2 legacy systems - One in C++ and other in C# that connect to the same access database. The access database is not password protected and we use the following connection string to connect to the databases
Provider=Microsoft.Jet.OLEDB.4.0; Persist Security Info=False ;Data Source= AlarmHistory.mdb
C# application polls a table in the database every 10 seconds. Once in while , the C# application crashes with the error message -
System.Data.OleDb.OleDbException: Cannot start your application. The workgroup information file is missing or opened exclusively by another user.
The log analysis revealed that both the applications are not accessing the database simultaneously ... Any idea on what could cause such a situation... Please Help
They might not be accessing the database at exactly the same time, but that error message indicates that they (or something else) is accessing the lock file at the same time. Is the poll opening and closing the connection each time? You could move the open and close to outside the timer so that the connection is opened and remains open for the life of the application.

How to debug the application after deployed in IIs?

Hai All,
I'm developing the application using .net 2008 and Oracle 10g as database. I have deployed the application in IIS, now when two users get logged into the same applicaion, same page at a time getting error as
"*Connection must be open for this operation.Cannot access a disposed object.object name: 'Oracle.DataAccess.Client.OralceConnection'.Connection must be open for this operation"*
Plz give a solution to solve this multiuser issue..
Thanks in Advance!!!!
The easiest way to look into what's happening on IIS is to deploy a debug build, connect to the machine the server is on, and run the CLR debugger. Of course, this is only really practical in a staging rather than live scenario (or you have dozens or even thousands of people hitting the breakpoint, and of course the whole thing freezes up while you are stepping through).
This case sounds a bit like you might have a connection object statically scoped, or otherwise shared between threads, rather than created as needed on each thread of execution. It's the sort of thing sometimes seen if someone tries to manually pool connection objects (which is pointless, indeed counter-productive, as the underlying connector objects are pooled for you).

Categories

Resources