用悲观并发方式处理数据库并发冲突以保证数据一直性的代码处理方法_SQL SERVER数据库_黑客防线网安服务器维护基地--Powered by WWW.RONGSEN.COM.CN

用悲观并发方式处理数据库并发冲突以保证数据一直性的代码处理方法

作者:黑客防线网安SQL维护基地 来源:黑客防线网安SQL维护基地 浏览次数:0

本篇关键词:处理并发代码方法
黑客防线网安网讯:  悲观处理方式是 采用SQLSERVER数据库中“事务+锁”!  先上伪代码再解释:  1.先解释2个要用到的锁  SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除  ...

  悲观处理方式是 采用SQLSERVER数据库中“事务+锁”!

  先上伪代码再解释:

  1.先解释2个要用到的锁

  SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表但不能更新删除

  SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除

  PS:这2个是表级锁要锁行加上SQL过滤条件即可数据库的默认隔离级别是readcommit,

  SqlCommand cmd = new SqlCommand("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;select * from Users WITH(rowlock) where id = 2", connection, st);重设事务的隔离级别可以用行锁

  2.在一个管理页面执行Update,Delete操作的时候(起码能得到实体的主键ID数据及其修改后的数据),在代码处理的时候:

  客户A在某个管理页面执行如下操作

   private void button1_Click(object sender, EventArgs e)
        {
            SqlTransaction st = null;
            using (SqlConnection connection = new SqlConnection(connectionString)) 
            {
               
                try
                {
                    connection.Open();
                    using (st = connection.BeginTransaction())
                    {
                
                        
                     
                        this.Cursor = Cursors.WaitCursor;
                        SqlCommand cmd = new SqlCommand("select * from Users WITH(HOLDLOCK) where id = 2;update Users set name = 'C罗',address = 'basi' where id = 2", connection, st);
           
                        cmd.ExecuteNonQuery();
                        System.Threading.Thread.Sleep(20000);
                        st.Commit();
                        MessageBox.Show("ok。。。s1");
                    }
                }
                catch
                {
                    st.Rollback();
                }
                finally
                {
                   connection.Close();
                    this.Cursor = Cursors.Default;
                }
            }
        }

  客户B在也在该管理页面执行如下操作  

              private void button1_Click(object sender, EventArgs e)
        {
 
            SqlConnection connection = new SqlConnection(connectionString);
            connection.Open();
           SqlCommand cmd = new SqlCommand("update Users set name = '大罗',address = 'basi' where id = 2", connection);
         
            cmd.ExecuteNonQuery();
                        
                        connection.Close();
                        MessageBox.Show("ok无事务的提交了");
            
        }

  那么用户A先进入改管理页面,并进行修改用户ID=2的用户操作,在A用户操作20秒之内,B用户也进入该管理页面进行操作修改用户ID=2的人,那么在A用户修改操作事务提交或回滚或该事务执行失败之前,用户B的操作会等待在队列中,直到A的事务提交释放悲观锁,B的隐式事务才会提交到数据库。

  这样就保证了数据的一致性。

  最后结果是用户ID=2的名字是大罗(先被改成C罗,后来改成大罗)

  业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希望在结算进行过程中(可能是几秒种,也可能是几个小时),数据再发生变化。此时,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓的 “ 锁 ” ,即给我们选定的目标数据上锁,使其无法被其他程序修改。


  悲观锁( Pessimistic Locking )

  悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。

  一个典型的倚赖数据库的悲观锁调用:

  select * from account WITH(HOLDLOCK) where name=”Erica”

  这条 sql 语句锁定了 account 表中所有符合检索条件( name=”Erica” )的记录。

  本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。

  以上就是项目中的采用悲观处理方式,欢迎大家讨论自己的处理方式。

    黑客防线网安服务器维护方案本篇连接:http://www.rongsen.com.cn/show-10514-1.html
网站维护教程更新时间:2012-03-21 03:05:43  【打印此页】  【关闭
我要申请本站N点 | 黑客防线官网 |  
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479

footer  footer  footer  footer