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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值