首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 第二书店 程序员
您的位置:软件测试频道-正文

高并发测试下的一些问题及解决2008-07-03 来自:lizhe1985  [收藏到我的网摘]

来源:希赛网

  测试在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 plaincopy to clipboardprint?
  public class TestPO {
  String id;
  String name;
  int num;
  ....
  }
  public class TestPO {
  String id;
  String name;
  int num;
  ....
  }

  映射文件 hibernate3: view plaincopy to clipboardprint?

  被测试方法(都配置有事务): view plaincopy to clipboardprint?

  public void testSave(int num) {
  TestPO po = new TestPO();
  po.setName("ronghao");
  po.setNum(num);
  theadTestDao.save(po);
  po.setName("haorong");
  }
  public void testSaveByJdbc(int num) {
  String sql = "insert into WFMS_TESTPO (ID,NAME,NUM) values (?,'RONGHAO',?)";
  Object[] params = new Object[]{num,num};
  jdbcTemplate.update(sql, params);
  sql="update WFMS_TESTPO set name='haorong' where id=?" ;
  params = new Object[]{num};
  jdbcTemplate.update(sql, params);
  }
  public void testSave(int num) {
  TestPO po = new TestPO();
  po.setName("ronghao");
  po.setNum(num);
  theadTestDao.save(po);
  po.setName("haorong");
  }
  public void testSaveByJdbc(int num) {
  String sql = "insert into WFMS_TESTPO (ID,NAME,NUM) values (?,'RONGHAO',?)";
  Object[] params = new Object[]{num,num};
  jdbcTemplate.update(sql, params);
  sql="update WFMS_TESTPO set name='haorong' where id=?" ;
  params = new Object[]{num};
  jdbcTemplate.update(sql, params);
  }

  测试用例: view plaincopy to clipboardprint?

  public void testSave() throws Exception {
  TheadtestTemplate template = new TheadtestTemplate();
  template.execute(new TheadtestCallback() {
  public void doInThead(int suquence) {
  // theadTestManager.testSave(suquence);
  theadTestManager.testSaveByJdbc(suquence);
  }
  }, 10);
  }
  public void testSave() throws Exception {
  TheadtestTemplate template = new TheadtestTemplate();
  template.execute(new TheadtestCallback() {
  public void doInThead(int suquence) {
  // theadTestManager.testSave(suquence);
  theadTestManager.testSaveByJdbc(suquence);
  }
  }, 10);
  }

  测试结果:不论是hibernate还是jdbc,并发情况下都很快就会引起sqlserver2000的死锁,换用两种数据库驱动jtds和jturbo死锁的情况没有变化。 结论:sqlserver2000数据库的lock配置策略,不支持,或者数据库本身,就不支持对不同的行做同时操作(或者支持不完善),所谓的行锁支持很不完善,死锁情况非常容易发生。 补充:我对数据库的一些实现机制也并不是很了解,所以这里也只能列出现象而不能解释死锁的根本原因。

推荐人评论

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

用户评论

正在载入评论列表...

是谁推荐了此篇文章

专家头像李哲
个人blog发送信息
李哲推荐的其他文章

热点新闻

热点评论

    精彩专题

    资源下载

    网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|版权声明|问题报告

    北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright 2000-2008, CSDN.NET, All Rights Reserved
    GongshangLogo