您的位置:首页 > 其它

LINQ学习之旅——第二站"LTQ"之并发访问冲突及处理

2011-09-16 23:05 197 查看
  在编写用户应用软件时,只要是涉及到数据库的操作,尤其是对于多用户并发访问数据库的情况,开发人员都要考虑如何来解决并发冲突的问题。当一个用户从数据库中读取数据并修改数据,最后把修改结果保存到数据库中,在这个过程中,另外一个用户也同样在查询和修改和上一个用户相同的数据,并早于上一个用户向数据库提交了更改,这时第一个用户在向数据库提交修改就发生了所谓的并发冲突。所以所开发的程序一定要提供对并发冲突检测和处理的机制。一般情况下,处理并发冲突有两种方式:乐观并发和悲观并发。下面详细介绍一下这两种处理并发冲突的方式。

  1.乐观并发:

  从字面意思上来看,就是说它对于并发冲突的发生持有乐观的态度,且认为大部分的程序运行时间里不会发生并发冲突。所以程序在访问和修改数据库时不会锁定要修改的数据,而是采用一种在修改时动态监测并发冲突的可能性的方法。乐观并发允许大量的用户访问数据库,也是目前应用最广泛的一种并发冲突处理方式。而LINQ TO SQL就提供了对乐观并发的支持,来帮助完成冲突检测和冲突处理任务。LINQ TO SQL提供了两种方法来检测并发冲突。这两种方式关键都在之前对象——关心映射(ORM)一节中所提到的内联属性Column中参数IsVersion和UpdateCheck的设置上。那么第一种就是用参数IsVersion来修饰实体类的列属性,如果实体类的某一列使用了IsVersion修饰并其值设置为true,这该列用于检测并发冲突。在用示例进一步说明之前,先把前几节都用到过的实体类Student做如下更改:

事务处理避免并发冲突

staticvoid Main(string[] args)
{
string str_conn =@"Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king";
DataContext dc =new DataContext(str_conn);

//使用事务将数据库中的记录锁定
using (TransactionScope t1 =new TransactionScope())
{
var students = dc.GetTable<Student>();

var student = (from stu in students
where stu.Name =="刘麻子"
select stu).Single();
//修改实体类对象
student.Name ="张麻子";

//模拟并发访问
using (TransactionScope t2 =new TransactionScope(TransactionScopeOption.RequiresNew))
{
SqlConnection conn =new SqlConnection(str_conn);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText ="update student set sname='刘晓光' where sname='刘麻子'";
cmd.CommandType = System.Data.CommandType.Text;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
//事务2提交
t2.Complete();
}

//提交数据修改到数据库
dc.SubmitChanges();
//事务1提交
t1.Complete();
}

Console.Read();
}


ii.结果:



原因在于事务1将数据库中数据锁住,进行数据修改,但并未提交事务,所以导致事务2一直等待事务1结束,而事务1的结束必须要等事务2结束,所以事务2不可能会有机会来执行,所以事务2最终等待超时抛出异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐