定时器机制及锁实现
2017-10-24 21:50
459 查看
应用场景
在需要定时执行任务时就需要代码实现定时器任务,但是现在的系统大多是分布式系统,N台业务逻辑服务器同一时刻执行任务,如果不作处理,务必会造成资源的严重浪费,严重情况还会引起业务的失败。所以此时就需要实现分布式锁来保证同一时刻只有一台服务器执行该任务,不仅节约了系统资源,在保证高可用的情况下,还能正常的保证业务逻辑的实现。代码实现
定时器
第一步
设置需要实现定时任务的bean与需要执行的方法名<bean id="jobDetail1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="Scheduler1"> </property> <property name="targetMethod" value="run"/> <!-- 是否允许任务并发执行。当值为false时,表示必须等到前一个线程处理完毕后才再启一个新的线程 --> <property name="concurrent" value="false"/> </bean>
第二步
执行该定时任务的频率,cron表达式工具详见:http://cron.qqe2.com/<bean id="Triggers1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail1"> </property> <property name="cronExpression"> <!--Cron表达式的格式:秒 分 时 日 月 周 年(可选), 30s一次--> <value>*/30 * * * * ?</value> </property> </bean>
第三步
将设置好的触发器纳管<bean id="Scheduler1" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="Triggers1"></ref> </list> </property> <property name="autoStartup" value="true"></property> </bean>
锁实现
锁实现依赖于数据库,表结构与代码参考如下:LockUtils代码如下:
package test.util; import java.util.Date; /** * 该类提供抢锁、释放锁操作<br/> * 保证N台服务器同一时刻只会有一台服务器执行某一操作<br/> * * @author */ public class LockUtils { private static final String UNLOCK = "UNLOCK"; private static final String LOCK = "LOCK"; /** * 抢锁 * * @param transCoreLockDao * @param lockKey * @return */ public static boolean getLock(TransCoreLockDao transCoreLockDao, String lockKey) { TransCoreLock transCoreLock = getTransCoreLock(lockKey, UNLOCK); return transCoreLockDao.updateByEntity(SQL.get(SQL.UPDATE_TRANS_LOCK_TO_GET_LOCK), transCoreLock) > 0; } /** * 释放锁 * * @param transCoreLockDao * @param lockKey * @return */ public static boolean releaseLock(TransCoreLockDao transCoreLockDao, String lockKey) { TransCoreLock transCoreLock = getTransCoreLock(lockKey, LOCK); return transCoreLockDao.updateByEntity(SQL.get(SQL.UPDATE_TRANS_LOCK_TO_RELEASE_LOCK), transCoreLock) > 0; } /** * 通过key和lock标识生成对象 * * @param lockKey * @param lock * @return */ private static TransCoreLock getTransCoreLock(String lockKey, String lock) { TransCoreLock transCoreLock = new TransCoreLock(); transCoreLock.setLockKey(lockKey); transCoreLock.setLockFlag(lock); transCoreLock.setUpdateDt(new Date()); return transCoreLock; } }
注意事项:
1.代码层面一定要极其注重还锁,否则容易影响下一次乃至以后所有的抢锁操作(正常逻辑及异常逻辑的还锁操作)2.定时器锁较依赖于时钟同步,如果出现时间不同步,则可能会出现,同时两台或N台服务器执行业务逻辑,原因是某台服务器抢到锁–>执行业务逻辑成功→还锁等一系列操作均已完成,也许只是用了几十毫秒时间,另外一台由于时间的未同步,又继续执行了业务逻辑
3.该实现方式建议不作为影响交易逻辑等重要环节的解决方案
相关文章推荐
- Linux内核进程调度以及定时器实现机制
- 【转】Linux内核进程调度以及定时器实现机制
- (原创)linux内核进程调度以及定时器实现机制
- linux内核进程调度以及定时器实现机制
- 定时器+工作队列 内核周期性任务的实现机制
- linux 中定时器的实现机制
- linux内核进程调度以及定时器实现机制(转载)
- Linux内核进程调度以及定时器实现机制(转)
- Nginx定时器机制的实现
- C#实现异步编程的两个简单机制(异步委托&定时器)及Thread实现多线程
- 利用定时器机制实现多线程编程
- 基于委托机制的定时器的实现
- 定时器+工作队列 内核周期性任务的实现机制
- Linux内核进程调度以及定时器实现机制
- 【转】深入剖析linux内核的定时器实现机制-动态刷新维护
- RxCache 的代码分析,含缓存时间duration的在代码中改变的自己实现的机制
- Java实现Qt的SIGNAL-SLOT机制(保存到Map中,从而将它们关联起来,收到信号进行解析,最后反射调用)
- TabHost实现机制_源码分析
- 利用OC的消息转发机制实现多重代理
- 在TabControl基础上实现的一个翻页机制