这里有并发问题吗? 如何在开发过程中测试它?

场景:存在’n’个团队,每个团队都在他们的虚拟“墙”上工作(如facebook的墙)。 每个团队只看到自己的墙和上面的post。 这些post可以由post的作者或其他团队成员编辑(如果这样配置的话。假设确实如此,因为它必须具备)。

设计/技术决策:使用Restlet + Glassfish / Java + Mysql的RESTful Web应用程序(编辑:使用Apache DBUtils进行数据库访问。没有ORM – 似乎有点矫枉过正)

问题:多个团队登录T1,T2和T3(比如说),每个团队都有一些成员。 团队级数据访问存在并发性,但团队之间不存在并发性 – 即不同的团队访问不相交的数据集。 为了优化对DB的频繁读/写,我们正在考虑一个TeamGateway,它控制对DB的访问以处理并发。 Web服务器将缓存团队检索的数据以加快读取速度(并帮助更新墙上post列表)

  • Q1:这是否需要(每个团队的TableGateway +缓存)? 如果不是,您如何建议处理?
  • Q2:如果是这样,TableGateway(每个团队)是否需要编码为线程安全(同步方法)? 假设我们有一个类/注册表TableGatewayFinder,它带有一个静态方法,返回TableGateway以用于该特定团队(使用hashmap)。

如果来自每个T1-T3登录的6个人那么只会创建3个TableGateways,它是否有助于捕获并发写入(提交之前的简单时间戳比较或“冲突标记”追加)并有效地管理缓存(我们计划拥有实体的身份映射 – 需要跟踪4-5个不同的实体.4个实体用于组合层次结构,另一个实体与4)中的每一个相关联?

一个单元如何测试网关(基于TDD或事后)?

提前致谢!

如果您只是写入数据库或DB上的缓存解决方案(例如Spring + Hibernate + EhCache等),您不必担心损坏表等。从低级别点来看,没有并发问题观点。

如果您想自己编写缓存并自己处理并发问题,那么这将需要一些努力。 如果你对每个分区的缓存进行分片并具有“全局锁定”(即在一个共同的互斥锁上synchronized ),并为任何访问获取此锁,那么这将是有效的,而它不是最高效的方法。 但是做一些其他事情而不是全局锁定会涉及很多工作。

虽然这很简单,但不确定为什么你想要使用身份哈希映射…我想不出你想要做的任何特定原因(如果你正在考虑性能,那么正常哈希映射的性能)在这种情况下你最不需要担心的事情!)。

如果您的实体是文章,那么您可能有另一种forms的并发问题。 就像SVN,Mercurial等版本控制软件解决的问题一样,即如果你没有将合并function应用到你的应用程序中,如果有人编辑某人的文章只是为了发现其他人已经“承诺”了另一个人,那就变得很烦人了。在您之前编辑等。是否需要添加此类function取决于用例。

至于测试你的应用程序。 对于并发性,unit testing也不错。 通过编写并发unit testing,捕获并发错误要容易得多。 编写并发测试非常困难,因此我建议您在编写之前阅读“Java Concurrency in Practice”等优秀书籍。 在集成测试之前更好地捕获并发错误,因为很难猜到到底发生了什么!

更新:
@Nupul:这是一个难以回答的问题。 但是,如果你只有18个人输入东西,我的赌注就是每次写入DB都会很好。

如果你没有在其他地方存储任何状态(即只存在于数据库中),你应该摆脱任何不必要的互斥锁(除非你有充分的理由在你的情况下这样做,否则你不应该存储除数据库之外的任何其他状态。 IMO)。

在做类似网络操作的事情时很容易犯错误并获得互斥体,从而导致极端的可用性问题(例如,应用程序不会响应很多秒等)。 并且很容易出现令人讨厌的并发错误,如线程死锁等。

所以我的建议是保留你的应用程序。 无状态,每次只写DB。 如果您发现由于数据库访问导致的任何性能问题,那么转向像EhCache这样的缓存解决方案将是最好的选择。

除非您想从项目中学习或必须提供应用程序。 由于性能要求极高,我不认为编写自己的缓存层是合理的。

unit testing可能不是并发问题的最佳方法。 相反,您可以尝试使用基于Web的性能工具(如JMeter或Rational Performance Tester)来测试它的执行方式,并在增加用户数量时获得有效的墙内容。 您可以使用这些工具为每个用户提供不同的发布行为。

专注于标题中的2个问题。

这里有并发问题吗?

是。 明显。 避免并发问题可能性的唯一方法是使产品具有单线程,这将产生重大的性能和可用性问题。

如何在开发过程中测试它?

这是一个很难的问题。

显然你需要进行unit testing。 但是经典unit testing并没有真正削减它的并发性问题,因为棘手的并发错误往往很少出现。

更好的方法是负载测试。 正如@Gnat所描述的那样。

但为了获得最佳结果,您需要确认测试不是(整个)解决方案,并添加以下内容:

  • 在设计,编码和测试并发应用程序方面经验丰富的员工。
  • 非常关注Goetz等人的“Java – Concurrency in Practice”的方法/建议。
  • 大量的设计和代码审查。
  • 彻底使用静态代码分析器来解决潜在的并发问题。