locked
wcf service ,concurrency lock right way to do RRS feed

  • Question

  • Hi Guys,

    I have written a wcf service and hosted it in IIS.
    It has 2 methods.

    1.Generate_ID()
    2.Insert_Record()

    Database consists of a table by name Test (ID primarykey , name varchar)


    Generate_ID methods generates the next uniqueID (incrementalvalue say  ) from the table Test.

    Insert_Record method inserts a record into table Test.inside insert_record just before
    inserting record into table  generate_id method is called to get the next unique id from the test table. and then that value is used for inserting.

    Example : insert into test values(generat_id(),'record1');


    By default the service instance mode is percall and concurrency is single

    I think if multiple clients(windows form clients) are calling insert_record method at same time.Generate_id will produce same id and results in the failure of operation (primarykey violation).

    So my question is if i used instance mode is single and concurrency is single, will it solve the issue or do i need to implement lock on a block of code in generate_id.

    suggestions and advices are welcome.



    Cheers,
    Friend.
    Wednesday, February 1, 2012 5:30 AM

Answers

  • Yes,By default the service instance mode is percall and concurrency is single it means,

    When the service is configured with ConcurrencyMode.Single, WCF will provide automatic synchronization to the service context and disallow concurrent calls by associating the context containing the service instance with a synchronization lock. Every call coming into the service must first try to acquire the lock. If the lock is unowned, the caller will be allowed in. Once the operation returns, WCF will unlock the lock, thus allowing in another caller.

    The important thing is that only one caller at a time is ever allowed. If there are multiple concurrent callers while the lock is locked, the callers are all placed in a queue and are served out of the queue in order.

    So In a given time there would be one Insert_Record() method would be processed by WCF irespective to n concurent call, i mean all concurent call would be placed on Queue and would be processed one by one.

    I do not think you would face any Concurent issue if you would go with default instance mode and Concurency.

    What Database you use For Generate_ID() ? For Sql Server You can set your incrementing column to use the identity property which gurentee to create a unique ID irespective of concurency.

    Still if you feel to handle your concurency issue,i would recomend to handle that on Database level rather on WCF service as some one earler in this post (Peter) said. And this link would help you with number of option

    http://stackoverflow.com/questions/3453411/sql-server-auto-incrementation-that-allows-update-statements/3462957#3462957

    For WCF concurency http://msdn.microsoft.com/en-us/library/orm-9780596521301-02-08.aspx

     


    Lingaraj Mishra
    • Marked as answer by Yi-Lun Luo Tuesday, February 7, 2012 11:35 AM
    Thursday, February 2, 2012 9:10 AM

All replies

  • Instance mode single and concurrency mode single will solve the locking problem but will introduce a new problem. By doing these 2 things you seriously limit the possible throughput of your service.

    The nice solution is to implement correct locking if the stored procedure that generates the next id.

    Did you also consider autonumer or GUIDs as unique identifier?


    If this post answers your quenstion, please mark it as such. If this post is helpful, click 'Vote as helpful'.
    Wednesday, February 1, 2012 6:34 AM
  • Hello....

    Generate_ID methods generates the next uniqueID (incrementalvalue say  ) from the table Test.


    By default the service instance mode is percall so for each call wcf service will create new instance of service and will get dispose after back to client side.

    So when there are multiple users as per your scenario you can use transactions (with isolation level = readcommitted) with WCF to insert record.

    Isolationlevel == readcommitted will lock the currently executed or modified row(s) and release after the completion of task.

    for more information How to implement transaction in WCF

    http://www.codeproject.com/Articles/38793/6-Steps-to-Enable-Transactions-in-WCF

    I hope this will help to solve your problem

     

     

     

    Regards, Hiren Bharadwa
    Wednesday, February 1, 2012 9:59 AM
  • Hi Hiren,

     

    I have seen that example before but it talks about 2 different services performing operations within a transaction. in my case i have 2 methods in one service  which many clients will be using to insert records into database table. i have implemented sql transactions in my wcf  but i tink when the service runs in multiple concurrency mode it will create conflicts (same id gets generated for 2 differnt calls). is there a way i can use lock statments in wcf code?.

    Cheers,

    Friend.

    Thursday, February 2, 2012 6:57 AM
  • Hi Peter,

    Just a thought, Instance mode single and concurrency mode multiple with lock statement in generateid method should solve the issue. am i thinking right?

    i mean something like

    generateid()

    {

    lock(static readonly object.)

    {

    code to generate id here ...

    }

    }

     

    Cheers,

    Friend.

    Thursday, February 2, 2012 7:14 AM
  • Yes,By default the service instance mode is percall and concurrency is single it means,

    When the service is configured with ConcurrencyMode.Single, WCF will provide automatic synchronization to the service context and disallow concurrent calls by associating the context containing the service instance with a synchronization lock. Every call coming into the service must first try to acquire the lock. If the lock is unowned, the caller will be allowed in. Once the operation returns, WCF will unlock the lock, thus allowing in another caller.

    The important thing is that only one caller at a time is ever allowed. If there are multiple concurrent callers while the lock is locked, the callers are all placed in a queue and are served out of the queue in order.

    So In a given time there would be one Insert_Record() method would be processed by WCF irespective to n concurent call, i mean all concurent call would be placed on Queue and would be processed one by one.

    I do not think you would face any Concurent issue if you would go with default instance mode and Concurency.

    What Database you use For Generate_ID() ? For Sql Server You can set your incrementing column to use the identity property which gurentee to create a unique ID irespective of concurency.

    Still if you feel to handle your concurency issue,i would recomend to handle that on Database level rather on WCF service as some one earler in this post (Peter) said. And this link would help you with number of option

    http://stackoverflow.com/questions/3453411/sql-server-auto-incrementation-that-allows-update-statements/3462957#3462957

    For WCF concurency http://msdn.microsoft.com/en-us/library/orm-9780596521301-02-08.aspx

     


    Lingaraj Mishra
    • Marked as answer by Yi-Lun Luo Tuesday, February 7, 2012 11:35 AM
    Thursday, February 2, 2012 9:10 AM