1

How to prevent multiple instance running at the same time on different machines. I want to check if other users working on same instance in real time, mean without wait to X time.

  • I'm using c# code.
  • that instances connect to same database.
bebosh
  • 806
  • 10
  • 25

4 Answers4

0

when you run your app, first check if no other machine is running this app, if not, insert a some identifier which means that currently machine XX is running your app. When you close the app update your db (or delete your identifier) in order to let other machines use your app.

If you want to increase the reliability, you can send some signal to the DB every XX time units for confirming that your machine is still using your app and if no signal arrives after XX time units, let other machines the option to use you app. this approach can let other users to use your app when from some reason some machine closed without report about it (for example, a connection issue).

you can do it even more sophisticated and check before each transaction or every XX time units that your machine is still eligible to use your app.

hope it's helps

Ofir
  • 5,049
  • 5
  • 36
  • 61
0

There are many ways for doing this some are:

  1. Check the windows process you app have to run a process if the process with the same name exist do not start your application.
  2. Secondly Maintain the logged-in users details if a user is already logged in with the same username and password and again login with that username and pass deny it.
  3. Also you can get the machine name at login and save the logged-in users machine names and if a user come from same name again deny it.
Sajid Hussain
  • 63
  • 2
  • 10
  • your first suggestion is wrong - his app run on different machines so checking if the process is running won't work – Ofir Dec 10 '13 at 07:32
  • second and third ways also wrong - i have more username and password to log in to the form and suggest if machine turned off suddenly without do log out ... suggest if the machine network cable is down. – bebosh Dec 10 '13 at 10:13
0

Create lock table in your database:

Locks
  LockId (primary key; not auto increment)
  MachineId (this is a machine identifier; can be ip if in same network, MAC or a guid/string you set in your application's config file)
  LockExpires (DateTime)

You seed your Locks table with one record. Example values: LockId = 1 (can be anything), MachineId = null, LockExpires = null.

In your program hardcode/configure the seeded LockId, to use it in your queries.

You will use three queries to set/check/delete lock:

-- SetLock
update Locks set
  MachineId = {MachineId you configured for the machine},
  LockExpires = adddate(minutes, {N}, getdate()) -- lock for N minutes; set to null to hold the lock indefinitely)
where 
  LockId = {hardcoded LockId} and
  (
  MachineId is null -- nobody holds a lock
  or LockExpires <= getdate() -- or lock expired
  or MachineId = {MachineId you configured for the machine} -- or you hold the lock
  )

-- CheckLock (if count > 0 then you hold the lock)
select count(*) from Locks 
where
  LockId = {hardcoded LockId} and
  MachineId = {MachineId you configured for the machine} and 
  LockExpires > getdate()

-- DeleteLock
update Locks set
  MachineId = null
where 
  LockId = {hardcoded LockId} and
  MachineId = {MachineId you configured for the machine} and 
  LockExpires > getdate()

When program starts you check if there is an instance running on the same machine (something like "How to determine if a previous instance of my application is running?").

If you are the only instance on this machine, you SetLock and CheckLock. If CheckLock says you don't hold the lock then get out else proceed.

In your application write the code (best in separate thread) to set/check the lock every (N - M) minutes. Where N is number of minutes you hold the lock and M is some small number (1 or 2) to ensure your lock doesn't accidentally expire.

When you exit the application, DeleteLock.

Remember, if your application crashes, no other instance can be run until lock expires. In worst case, no application will be able run for N minutes (well, in the worst case, you are setting LockExpires to null and no application will run until you manually change the MachineId to null).

Similarly, if you don't reset the lock frequent enough, your lock might expire before you reset it and another application can run in that time frame.

So set the numbers according to your preferences and ability to code without bugs :-). The N = 4 to 10 and M = 1 to 2 should work if you can live without application running for few minutes.

Community
  • 1
  • 1
Luc
  • 1,488
  • 1
  • 13
  • 31
  • I know that way, but it similar session way as a web applications. I wanna way to check if user working on the instance now or not, mean I don't need to LockExpires – bebosh Dec 10 '13 at 10:00
  • If you're trying to prevent same user from logging in from different machines, replace MachineId with UserId. Or even use both (and alter queries accordingly), this way you can tell the user on which machine he/she is already logged in. – Luc Dec 10 '13 at 10:27
-1

If you are using "Sql Server", you can set your database to "Single User Mode"

Once in this mode, only the current connection is permitted to query or modify the database's data or schema. If any other users or processes attempt to make a connection to the database, they receive an error.

The simplest method to set a database into single user mode is to use the following command:

ALTER DATABASE database-name SET SINGLE_USER

Before everything, your program should check if it's can able to connect the database, if connection established, program can runs normally in this scenario.

Fırat Deniz
  • 868
  • 8
  • 11
  • 1
    My question is how to lock instance NOT lock the database, suggest i wanna use more instances working on the same database :) – bebosh Dec 10 '13 at 10:08