定时器机制及锁实现
来源:互联网 发布:c4d软件 编辑:程序博客网 时间:2024/06/04 19:51
应用场景
在需要定时执行任务时就需要代码实现定时器任务,但是现在的系统大多是分布式系统,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.该实现方式建议不作为影响交易逻辑等重要环节的解决方案
阅读全文
0 0
- 定时器机制及锁实现
- Nginx定时器机制的实现
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- android几种定时器机制及区别
- 深入剖析Linux内核定时器实现机制
- 基于委托机制的定时器的实现
- 前端开发工具技巧介绍—Sublime篇
- 14-面向对象(接口和抽象类的区别)1 14-面向对象(接口和抽象类的区别)2 14-面向对象(接口和抽象类的区别)3
- PAT1061 判断题
- React JSX
- Codeforces587B-DP+优化
- 定时器机制及锁实现
- 深度学习————AI的进化之匙
- 实习项目回顾
- ubuntu 中文安装后需要卸载的中文字体
- 优先队列——A-B
- 在阿里云服务器(9.9学生版)上Cmake 构建Rosetta,并仅编译AbinitioRelax
- 6. ZigZag Conversion leetcode
- Windows编程基础--第8节 MFC对话框控件访问的七种方法(上)
- 01-面向对象(接口的应用)1 01-面向对象(接口的应用)2 01-面向对象(接口的应用)3