以前就很担心并发,只是一直不知道该怎么处理。虽然,知道有几种不同的锁类型,对应什么情况使用和类型的锁。但是,一直没看到在c#代码中是如何体现的。
后来,有人提到过,不用自己考虑。数据库自己就替你考虑了。换言之,我的理解,数据库会针对你的sql语句,和数据库设置的锁策略(当然,如果不会自定义时相当于用默认的)。
以为,只要自己对要批量处理的操作建立事务就解决了。
今天在做的时候,事务是正常执行了,但是测试的结果是,仍然有问题。
举个实际的例子: 单据信息的保存。一般数据库表分为主子表的形式。
单据头对应主表,单据体对应子表,主表与子表之间通过主表id(唯一的,自增的)与子表关联。这个表结构及关联字段是参考成熟的大型系统的结构的。
0 创建事务
1 保存主表。主表有自增id字段。
2 获取刚才保存记录的id值,用的max(id)。
3 将该id值,赋值给对应记录集(datatable)中对应字段的值。
4 将该datatable保存到数据库中。
5 提交事务。
我做的测试是,在1和2步骤之间,暂停5秒,手工通过查询分析器,向主表插入一条记录。以此模拟如果在并发的情况下,此事务是否锁定的相关表。当然,实际当中,即使在很多并发的情况下,正好并发的插入操作在1、2步骤之间的情况也是可能性极低的。而如果插入主表的操作在其他步骤之间,则不影响数据的正确性。 测试的结果是,很不幸。获取的max(id)并不是自己保存单据的单据头对应记录的id。
请教大家,如何解决。
后来,有人提到过,不用自己考虑。数据库自己就替你考虑了。换言之,我的理解,数据库会针对你的sql语句,和数据库设置的锁策略(当然,如果不会自定义时相当于用默认的)。
以为,只要自己对要批量处理的操作建立事务就解决了。
今天在做的时候,事务是正常执行了,但是测试的结果是,仍然有问题。
举个实际的例子: 单据信息的保存。一般数据库表分为主子表的形式。
单据头对应主表,单据体对应子表,主表与子表之间通过主表id(唯一的,自增的)与子表关联。这个表结构及关联字段是参考成熟的大型系统的结构的。
0 创建事务
1 保存主表。主表有自增id字段。
2 获取刚才保存记录的id值,用的max(id)。
3 将该id值,赋值给对应记录集(datatable)中对应字段的值。
4 将该datatable保存到数据库中。
5 提交事务。
我做的测试是,在1和2步骤之间,暂停5秒,手工通过查询分析器,向主表插入一条记录。以此模拟如果在并发的情况下,此事务是否锁定的相关表。当然,实际当中,即使在很多并发的情况下,正好并发的插入操作在1、2步骤之间的情况也是可能性极低的。而如果插入主表的操作在其他步骤之间,则不影响数据的正确性。 测试的结果是,很不幸。获取的max(id)并不是自己保存单据的单据头对应记录的id。
请教大家,如何解决。
至于select @@identity。其实和我的目的都是一样的,只不过我不知道为什么,当我用这种方式来获取的时候,总是报错。感觉,不能够将sql server里的变量直接通过字符串传过去。
也许我该用参数的形式试一下。