加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

高并发测试下的一些问题及解决

发布时间:2020-12-12 15:52:01 所属栏目:MsSql教程 来源:网络整理
导读:测试在sqlserver2000上进行,对工作流操作的相关方法在单元测试里进行多线程并发。测试发现sqlserver出现死锁的情况相当多,一些典型的情况: 1、对同一张表先insert再update是很快会引起死锁的,不管操作的是否是同一记录 解决方法:对于同一记录,需要调整

测试在sqlserver2000上进行,对工作流操作的相关方法在单元测试里进行多线程并发。测试发现sqlserver出现死锁的情况相当多,一些典型的情况:

1、对同一张表先insert再update是很快会引起死锁的,不管操作的是否是同一记录

解决方法:对于同一记录,需要调整hibernate的映射策略,使得一次insert完成操作。对于不同的记录需要在代码中手动flush,使得update先于insert。

2、对两张表进行多次update操作时,两张表交替update也会很快引起死锁

解决方法:在代码中手动flush,保证对两张表的update不会出现交替的情况。

3、部分大范围扫描的select和update混合也会导致死锁

解决方法:优化sql,尽量减少sql语句,通过给po增加持久化字段的方式减少关联查询

经过优化,大部分情况下数据库死锁的情况得以避免,另外奇怪的是通过事件探查器在死锁时并未发现锁升级的事件。但是在一些特殊情况下(例如多个并发汇聚的 直接联合),死锁依旧发生。最后不得不对方法进行synchronized关键字同步,这个通过synchronized flush完成。业务方法不必同步,最后批量操作数据库时进行同步。

换oracle进行测试,在未synchronized的情况下,未发生死锁情况。由此可见sqlserver与oracle锁实现机制存在很大的差别。另,同事说,sqlserver2005后性能和机制发生了很大的变化,未测试。

补充一下我的一个最简单情况下的测试用例: PO:

view plain copy to clipboard print ?
  1. public?class?TestPO?{??
  2. ??
  3. ????String?id;??
  4. ??
  5. ????String?name;??
  6. ??
  7. ????int?num;??
  8. ??
  9. ?????
  10. ??
  11. ????....??
  12. ??
  13. }??
映射文件 hibernate3: ?
  1. <hibernate-mapping?default-access="field">??
  2. ??
  3. ??<class?table="WFMS_TESTPO"?name="com.eway.workflow.test.po.TestPO">??
  4. ??
  5. ??
  6. ??
  7. ????<id?name="id"?column="ID"><generator?class="uuid"?/></id>??
  8. ??
  9. ??
  10. ??
  11. ????<property?name="name"?column="NAME"?type="string"/>??
  12. ??
  13. ??
  14. ??
  15. ????<property?name="num"?column="NUM"?type="integer"/>??
  16. ??
  17. ??
  18. ??
  19. ??</class>??
  20. ??
  21. </hibernate-mapping>??
被测试方法(都配置有事务): ?
  1. public?void?testSave(int?num)?{??
  2. ??
  3. ????TestPO?po?=?new?TestPO();??
  4. ??
  5. ????po.setName("ronghao");??
  6. ??
  7. ????po.setNum(num);??
  8. ??
  9. ????theadTestDao.save(po);??
  10. ??
  11. ????po.setName("haorong");??
  12. ??
  13. }??
  14. ??
  15. ??
  16. ??
  17. public?void?testSaveByJdbc(int?num)?{??
  18. ??
  19. ????String?sql?=?"insert?into?WFMS_TESTPO?(ID,NAME,NUM)?values?(?,'RONGHAO',?)";??
  20. ??
  21. ????Object[]?params?=?new?Object[]{num,num};??
  22. ??
  23. ????jdbcTemplate.update(sql,?params);??
  24. ??
  25. ????sql="update?WFMS_TESTPO?set?name='haorong'?where?id=?"??;??
  26. ??
  27. ????params?=?new?Object[]{num};??
  28. ??
  29. ????jdbcTemplate.update(sql,?params);??
  30. ??
  31. }??
测试用例: ?
  1. ?????public?void?testSave()?throws?Exception?{??
  2. ??
  3. ????????TheadtestTemplate?template?=?new?TheadtestTemplate();??
  4. ??
  5. ????????template.execute(new?TheadtestCallback()?{??
  6. ??
  7. ????????????public?void?doInThead(int?suquence)?{??
  8. ??
  9. //???????????????theadTestManager.testSave(suquence);??
  10. ??
  11. ????????????????theadTestManager.testSaveByJdbc(suquence);??
  12. ??
  13. ????????????}??
  14. ??
  15. ????????},?10);??
  16. ??
  17. ????}??
测试结果:不论是hibernate还是jdbc,并发情况下都很快就会引起sqlserver2000的死锁,换用两种数据库驱动jtds和jturbo死锁的情况没有变化。 结论:sqlserver2000数据库的lock配置策略,不支持,或者数据库本身,就不支持对不同的行做同时操作(或者支持不完善),所谓的行锁支持很不完善,死锁情况非常容易发生。 补充:我对数据库的一些实现机制也并不是很了解,所以这里也只能列出现象而不能解释死锁的根本原因。

http://www.blogjava.net/ronghao 荣浩原创,转载请注明出处:)?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读