关闭

SQL Server 2000+ADO.NET实现并发控制

545人阅读 评论(0) 收藏 举报

http://www.cnblogs.com/zhenyulu/articles/330494.html 

参考了上面这片对并发控制处理的文章,有些迷茫,自己做了实验,如下:

private static string connstr = "Server=(local);Database=DBApp;Trusted_Connection=True;";
        SqlConnection conn;
        SqlConnection conn2;
        SqlTransaction tran;
        SqlTransaction tran2;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Setup();
            //读取数据
            SqlCommand cmd = conn.CreateCommand();
            cmd.Connection = conn;
            cmd.CommandText = "select * from SC where ID=1 and cno=1";
            cmd.Transaction = tran;

            try
            {
                SqlDataReader dr=cmd.ExecuteReader();
                while (dr.Read())
                {
                    textBox1.Text = dr[0].ToString();
                    textBox2.Text = dr[1].ToString();
                    textBox3.Text = dr[2].ToString();
                }
                dr.Close();
               
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                tran.Rollback();
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Setup();
            //保存数据
            SqlCommand cmd = conn2.CreateCommand();
            cmd.Connection = conn2;
            cmd.CommandText = "update SC set mark="+Convert.ToDouble(textBox3.Text.ToString())+" where ID=1 and cno=1";
            cmd.Transaction = tran2;

            try
            {
                cmd.ExecuteScalar();
                tran2.Commit();
                tran.Commit();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                tran2.Rollback();
            }
            finally
            {
                conn.Close();
                conn2.Close();
            }
        }

        private void Setup()
        {
            conn = new SqlConnection(connstr);
            conn.Open();
            conn2=new SqlConnection(connstr);
            conn2.Open();

            tran = conn.BeginTransaction(IsolationLevel.RepeatableRead);
            tran2 = conn2.BeginTransaction(IsolationLevel.RepeatableRead);

            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }

同时开两个窗口,依次在两个窗口内对数据库进行操作,RepeatableRead模式下,保存操作都失败,究其原由是在三封锁对应RepeatableRead模式,该模式对数据读加了S锁(共享锁),并且要到事务结束才会释放,第一个事务在需要update的时候,必须给数据加x锁(写锁),因为此时第二个窗口的事务尚未结束,也就是说s锁还加在这个处理之上,在s锁未失效的情况下,其他事务只能对该数据对象加s锁而不能加x锁,从而造成了事务一也就是窗口一在更新的时候出现死锁,等待窗口二事务的解锁。超时后,事务一处理回滚,更新不成功。

这种方式,虽然能避免并发,但是处理方式不能友好,觉得还是可以用Scott Mitchell在ASP.NET2.0数据指南中的方法,在where字句中处理并发问题。关于效率问题,以后有时间再做测试。

以上两个事务,在同时改为ReadCommitted的模式下,在并发时,测试失败,两个窗口都可以更新数据。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:91462次
    • 积分:1615
    • 等级:
    • 排名:千里之外
    • 原创:52篇
    • 转载:61篇
    • 译文:6篇
    • 评论:9条
    最新评论