Database level lock in Microsoft SQL Server : schema migrations - c#

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.

Related

Is OPENROWSET a "production-safe" method?

I'm working on a desktop app that was developed about 5 years ago using C# and mssql server 2000.
This app uses OPENROWSET to load some xls files, and it worked just fine til the institution in where I work upgraded databases (to something like msserver 2019 or sort of), and OPENTOWSET stop working.
Despite knowing there's plentiful of procedures and recipes to fix this issue (which I cannot apply coz database runs on server), my company's DBA is telling me the only way to fix such problem is to give admin-privileges to the app-user, and he cannot do that because of safety rules - dropping the problem to me. Now I have to replace OPENROWSET with something else.
So the question is: is that true?
There's no way for a skilled DBA to make OPENROWSET work on a remote DB with regular/non-admin user, fixing those errors about permissions and linked servers?
Is OPENROWSET "mature-or-safe-enough" to make it run on nowadays production servers?
It looks like you are attempting to open excel files from within your database. In which case, the default setup would not allow this:
https://learn.microsoft.com/en-us/sql/t-sql/functions/openrowset-transact-sql?view=sql-server-ver15#remarks
OPENROWSET can be used to access remote data from OLE DB data sources
only when the DisallowAdhocAccess registry option is explicitly set to
0 for the specified provider, and the Ad Hoc Distributed Queries
advanced configuration option is enabled. When these options are not
set, the default behavior does not allow for ad hoc access.
When accessing remote OLE DB data sources, the login identity of
trusted connections is not automatically delegated from the server on
which the client is connected to the server that is being queried.
Authentication delegation must be configured.
It sounds like this may possibly have been configured way back in the past for previous databases, but the DBA who now sees this regards it as a bit of a security problem. Whether or not he is right depends very much on how you use this, but it does sound like something that would be better avoided.
It may be better to load the excel files in your C# application and then send the BULK data to sql server to just save.

Background running app in asp.net c#

I want to make a background running desktop app using asp.net c#.
The idea is to check a local database table and get all data from that table in order to insert all those data in live database table.
If there is any better solution for that scenario please suggest me one.
It seems that what you want to solve is moving data from multiple local databases into a central one so you can consume it via an asp.net website.
I won't be discussing application part since that's an easy problem to solve once you can connect to a db that has all the data you need.
There are several things to consider here:
Recurrence (one time migration vs continuous synchronization)
Direction (do you need to sync one-way from local to central or two-way)
Data Contract (do local databases have same or different schema than central database)
The Data Contract is your biggest problem if schemas are different since you will need to design at least a target schema for the central database that can take in data from local dbs.
Even if schemas are identical, you will need to devise a way that data is partitioned in central database, you might need to introduce a sourceDatabaseId column in your tables so you won't have conflicting primary keys (you won't have this problems if your primary keys are guids)
The others can be solved either building:
A windows service - Inputs: periodicity (e.g. every hour), source db and target db connection strings. You will have a main loop that waits until time to run has come (based on periodicity) and fetches data from source db and saves them into target db (preferably in batches)
A console application - Inputs: source db and target db connection strings. You will just move data in batches. You can configure a Scheduled Task on the server that will perform scheduled runs of your console application to solve the periodic running part.
You would set up one such windows service or scheduled console app per local database.
If you have complex databases you can look into tools like Microsoft Sync Framework to perform this data synchronization.
you can develop a windows service to do this type of work and install on server with timer setting.

How to Synchronize SQLServer Database and MySQL Database

My Scenario:
I have two applications. First one is a website which is connected to MySQL Database and 2nd one is a Desktop Application which is connected to SQL Server2008 R2 Database.
The Desktop application updates records locally and the MySQL database is updated online though the website.
Problem:
Two different databases, how can we update at the spot when changes are made either in MySQL or SQL Database?
What I Want:
Databases should be synchronized to each other (e.g. if changes are made in MySQL then SQL server database should be updated, or if changes are made in SQL Database then MySQL database should be updated)
Could anybody please suggest some code, any idea, or any solution to solve this issue?
Make use of Restful API's to Update information from MS SQL server to MYSQL server.
One of the first things I would point out is that complete and perfect syncing is not possible. Unfortunately there will be data types that exist in SQL Server that don't exist in MySQL and vice versa.
But assuming the data types are pretty simple and the schemas are similar, here are some options:
Use a service bus. You can write an application that monitors both database systems and when it sees a change, it pushes an object onto the service bus. Listeners to the service bus will see the objects and write them to the appropriate destination.
Use triggers like Alex suggested. SQL Server can have CLR code execute on a trigger. The CLR code could be some C# that writes directly to MySQL. Takes some setup, but it's possible. I've investigated running a process from a trigger in MySQL and all options are ugly. It's possible, but security is a major concern. The idea is that a record is changed, trigger is fired and an external process is run.
Write an application that constantly looks for "diffs" in tables and moves data back and forth. You'll need to modify all tables to make sure there is support for date/time stamps for each record so you can track when a record has "changed".

More than one application able to access the same database in SQL Server at a same time?

I'm very new to .NET, C# and SQL Server.
I need to develop a socket application using C#. That application should insert, delete, update, etc the data in database with respect to some request.
I need to develop another windows service application using C# that sends the data in the database to the web application through http.
The both applications run in the same system. The database is SQL Server. Both the applications use the same database.
I am unsure if while one application is deleting or inserting data in the database, then is the other application still able to access the database at a same time.
Sql Server can handle multiple requests just fine. Each connected client gets a different spid.
However, it is up to your sql server code (batches or sprocs) to handle data conceurrency issues via isolation levels and transactions. So in order to control one user reading data while others are updating, deleting etc..., you need to use isolation levels and locks.
Isolation levels:
http://msdn.microsoft.com/en-us/library/aa213034(v=sql.80).aspx
Also: http://dbalink.wordpress.com/2008/05/27/isolation-levels-and-locks-in-sql-server-2005/
Good writeup on transactions:
https://web.archive.org/web/20210614153200/http://aspnet.4guysfromrolla.com/articles/072705-1.aspx
I think that the simple answer is yes - multiple applications/people can access a database at the same time.
You may want to read up on transactions within a database and concurrency:
http://en.wikipedia.org/wiki/Atomicity_(database_systems)
http://msdn.microsoft.com/en-us/library/cs6hb8k4(v=vs.80).aspx
It is possible to access the same sql server database by as many applications as you want. If you are afraid that one application can attempt to read the data being changed by another one at the same time, read about transactions and isolation. But in very short, if you make a small atomic change which requires one line of sql code only, you probably shouldn't care about this at the moment.

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

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.

Categories

Resources