首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASP .NET WebMethods同步

ASP .NET WebMethods同步
EN

Stack Overflow用户
提问于 2013-09-15 12:35:17
回答 1查看 528关注 0票数 1

我在asp.net .asmx服务中有一个add方法,wich应该检查数据库中是否有记录,如果没有记录,它应该添加记录。

简化的代码示例如下:

代码语言:javascript
复制
object Mutex = new object();
[WebMethod]
public void InsertIfNotExists(string CLI)
{
    lock (Mutex)
    {
        using (SqlConnection conn = new SqlConnection(ConnectionString))
        using (SqlDataAdapter adapter = new SqlDataAdapter())
        using (DataSet ds = new System.Data.DataSet()){
        {
        //I log with log4net
        logger.Debug("InsertIfNotExists: Start Function: CLI:" + CLI);
        int dummy = 0;

        string sql = "SELECT  * CLI Promote where CLI=" + CLI + " ";
        adapter.SelectCommand = new SqlCommand(sql, conn);
        adapter.Fill(ds);
        DataTable t = ds.Tables[0];

        logger.Debug("InsertIfNotExists: " + t.Rows.Count + " records found for CLI:" + CLI);

        if (t.Rows.Count == 0)
        {
            logger.Debug("InsertIfNotExists: starting to add to table: CLI:" + CLI);

            DataRow dr = t.NewRow();
            dr["CLI"] = CLI;
            dr["DateOfSend"] = DateTime.Now;

            InsertToTable(t, dr, sql);
            logger.Debug("InsertIfNotExists: added to table: CLI:" + CLI + ", starting re-check");

            //checking if exist more then one lines - one more time
            sql = "SELECT  * CLI Promote where CLI=" + CLI + "";
            adapter.SelectCommand = new SqlCommand(sql, conn);
            adapter.Fill(ds);
            t = ds.Tables[0];

            logger.Debug("InsertIfNotExists: re-check for CLI:" + CLI + ", records count=" + t.Rows.Count);             
        }
        logger.Debug("InsertIfNotExists: Finish Function for CLI:" + CLI);
        }
    }
}

实际上,它会执行更多的检查和逻辑,这就是为什么我在.net中实现它,而不是在SQL语句本身中实现它,但本质上就是这样。

大多数情况下,代码运行良好,但有时由于多线程而进入竞争状态,尽管我使用了lock。

我今天得到的样本输出:

代码语言:javascript
复制
2013-09-15 11:47:14,145 [21] DEBUG Namespace.Service1 InsertIfNotExists: Start Function: CLI: 0501234567
2013-09-15 11:47:14,145 [13] DEBUG Namespace.Service1 InsertIfNotExists: Start Function: CLI: 0501234567
2013-09-15 11:47:14,148 [21] DEBUG Namespace.Service1 InsertIfNotExists: 0 records found for CLI: 0501234567
2013-09-15 11:47:14,148 [21] DEBUG Namespace.Service1 InsertIfNotExists: starting to add to table: CLI: 0501234567
2013-09-15 11:47:14,148 [13] DEBUG Namespace.Service1 InsertIfNotExists: 0 records found for CLI: 0501234567
2013-09-15 11:47:14,148 [13] DEBUG Namespace.Service1 InsertIfNotExists: starting to add to table: CLI: 0501234567
2013-09-15 11:47:14,149 [21] DEBUG Namespace.Service1 InsertIfNotExists: added to table: CLI: 0501234567, starting re-check
2013-09-15 11:47:14,149 [13] DEBUG Namespace.Service1 InsertIfNotExists: added to table: CLI: 0501234567, starting re-check
2013-09-15 11:47:14,154 [27] DEBUG Namespace.Service1 InsertIfNotExists: Start Function: CLI: 0501234567
2013-09-15 11:47:14,157 [27] DEBUG Namespace.Service1 InsertIfNotExists: 2 records found for CLI: 0501234567
2013-09-15 11:47:14,157 [27] DEBUG Namespace.Service1 InsertIfNotExists: Finish Function for CLI: 0501234567
2013-09-15 11:47:14,183 [13] DEBUG Namespace.Service1 InsertIfNotExists: re-check for CLI: 0501234567, records count=2
2013-09-15 11:47:14,184 [21] DEBUG Namespace.Service1 InsertIfNotExists: re-check for CLI: 0501234567, records count=2
2013-09-15 11:47:14,185 [13] DEBUG Namespace.Service1 InsertIfNotExists: Finish Function for CLI: 0501234567


2013-09-15 11:49:19,626 [21] DEBUG Namespace.Service1 InsertIfNotExists: Start Function: CLI:0507654321

我们在这里看到的是,有3个线程试图在并行的表中插入CLI 0501234567。线程21和13进入竞赛条件,每一个都插入了1项记录。然后线程27也尝试插入一个记录,但找到了现有的记录并退出。

为什么他们锁在互斥锁上就这么做了?

注意:线程21永远无法完成--我认为它是由线程21中的异常引起的,因为我试图在实际函数中重新检查之后删除“附加”行,然后尝试执行它的第二个线程应该进入异常。我知道这很难看,但这是我目前唯一的解决办法,我想知道如何正确地做这件事。

为什么asp.net的行为是这样的?在没有种族条件的情况下,完成该任务的正确方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-15 19:24:13

锁定发生的对象必须是静态的,否则服务中的每个请求都会有一个该对象的实例。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18812429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档