分类存档: 学习笔记

Java与AS3中的继承与构造函数

啊嘞!?

分布式系统中的hibernate缓存

最近工作中遇到一个比较有趣的问题,在应用层中某个API针对同一参数查询返回的结果反复不定,大概过两分钟左右以后返回数据就稳定了。

问题只出在测试环境,在开发环境中完全不能重现。最开始分析认为是api的isolation level的问题,感觉是更新数据的事务遇到问题被回滚;而几乎应用层所有API的隔离级别被设为了read-uncommited。但是实际的测试和日志都表现为数据是被成功写入数据库了,并且读未提交理论上只能够读到一次脏数据,而不应该出现数据反复不定的情况。另,该应用不支持远程事务回滚。

不是数据库层面的问题,那么就应该是出在缓存上了,这又要遇到另一个疑问,假设是数据库缓存出错,那么每次读到的数据也都应该是缓存中的值,也应该是稳定的——除非存在多个缓存。后来对比开发环境和测试环境发现了区别,测试环境中的服务器有两个实例(开发环境只有一个),这样答案就有解了,从逻辑上来讲这两个服务器实例必然是对前面API查询的数据进行了不同的缓存。而后对持久层的配置文件的分析也证明了这一点,有人在hibernate配置中对某些持久化对象进行了缓存,TTL也正好是前面的120秒。

但是这种更新数据库后,hibernate难道不支持同步更新缓存吗?答案是可以的,程序员也可以在应用层端代码中对目的缓存进行强制清空,然而那不是违背了设置缓存的初衷么?并且,在分布式系统中这个就比较头疼,hibernate是不能够主动的去监视数据库变动的,也就是说,你调用服务器A上的API查询了数据后,就只有服务器A的hibernate缓存能够得到刷新。两台服务器就会出现两个结果,在生产环境更多的服务器的情况下,问题就变得更有趣了。当然,你也不能要求数据库系统去主动通知持久化层做刷新缓存的工作——哥不是干这个的。

好吧,hibernate的缓存本来就不是分布式缓存,常见的持久化技术也大多是针对单服务器的。这种情况下,就需要搭建另一个异步系统(例如JMS)在数据库更新的同时发消息通知到所有hibernate实例对应的应用系统,让他们自己去完成缓存的更新。公司的架构蛳们正在做分布式系统的二级缓存,很好奇他们的具体实现,后话。

身份证里面的校验

身份证的最后一位绝对不是神马性别的象征啊(倒数第二位才是),这是一个校验位,将前17位乘以不同的系数之后相加,得到的和值再除以11取余,便能得到一个0-10之间的余数,再将这个余数作为下标到校验码数组中取到对应的值,便得到该身份证对应的校验码。将其与身份证最后一位对比,便能辨别身份证真伪。
这个校验是不严谨的,需要结合身份证的区位码跟生日信息,当然还有性别码才能进一步进行辨认。

附:系数数组 [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]
校验码数组 [ "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" ]

写的验证小应用一枚

身份证最后一位为X的孩子你伤不起啊,这个位是‘2’ 啊。。。