鸟儿和猫头鹰,只是作息不一样,但都能享受到一天中难得的安静。我原来是一只“猫头鹰”,现在是0:00休息的“猫头鹰”又是6:30工作的“鸟儿”。这段时间心态最为平和~。
最近项目中有一个页面某部分移动的需求,当点击某模块下移时其向下移动1,同时其下面的模块上移。有两种思路:
1、页面排序信息插入数据库时,保证严格有序插入,这样就可以做到,当前顺序总是小于其后顺序,大于其前面顺序,当下移时只要当前顺序+1,其后顺序-1就可以。当上移时只要当前顺序-1,其前顺序+1。但是这样存在一个问题,如何做到严格有序(相差1升序)插入?第一反应是每次插入时都去获取当前表最大顺序,然后+1,但是细想如果并发将出现问题,比如:当A、B两个线程同时添加数据时,都获取到了最大顺序seq,然后它们各自走自己的逻辑,最终数据将出现A、B的顺序都为seq+1。当然你会说采用加锁(全局锁)的方式处理,这样可以解决多线程问题,但是对于集群也就是多进程,这就是“死结”(事无绝对),因为无法共享内存。Hibernate的hilo策略就是一个例子,保证同一个数据库主键不会重复,但是和我的需求有出入,其是不连续的。
2、在上述的分析中,考虑到mysql的主键是自增的,但也有可能不连续。只能暂时否定第一种思路,采用交换seq的方式来解决问题。具体当插入数据时,获取主键id,然后将该id更新为当前记录的seq。这样就保证了升序。那么上移下移时,只要交换相邻记录的seq就可以完成操作。但是要保证每次交换都是从数据库获取最新seq,并防止页面重复提交,否则会导致多线程问题。
这个需求,是页面布局,应该尽量避免多人操作。比如A打开该页面没有操作,B打开该页面移动了顺序,当A再移动时可能无法达到其效果,这里我是不会判断A当前位置的,所以A再次移动后可能跑到了末尾。