最近由于用户使用反向代理,而代理服务器的读取超时只有1分钟,所以在NC上执行较长时间的业务需要改成异步任务,
并且提供异步任务监控,由此避免客户端发送IO异常和提升用户体验,这其中涉及到并发情况下的锁的问题,事务的问
题,调用信息的问题和token信息的问题,这里我讲讲我阅读NC6锁的相关代码的几点笔记
原理:
所有锁信息存在单例对象成员位置的一个同步容器里,加锁即put,如果锁存在加锁时返回false,解锁即remove,具体实现可以看LockService4DataSource这个类
普通锁:
需要自己加锁,自己解锁
注意
1.加/解锁的方法调用时,userid和ds参数没有用,全部可以为null,这些信息是从调用信息
InvocationInfoProxy里获取的,谁加的锁谁才能解锁
2.异步任务时,如果采用
try{
lock
todo
}finally{
unlock
}
这种写法,同一个用户同时操作三次,第一次上锁,第二次解锁,第三次又可以上锁了,如果操
作时间较长,锁没有意义,可以换成
if(lock){
try{
todo
}finally{
unlock
}
}else{
new LockFailedException();
}
3.多线程时,可能多次事务提交
因为在finally在事务提交之前执行,所以在解锁之后,线程被打断,就有可能出现这种问题,这种
问题动态锁可以解决
动态锁:
自己加锁,事务提交后,远程调用前会自动释放锁,具体可以阅读RMIHandlerImpl
注意:
1.动态锁的信息会将所信息存一份在自己的线程本地变量里,解锁的时候会将线程里所有的动
态锁释放,由此如果动态所一旦没有被释放,就永远无法解锁,只能重启服务
2.不适用于普通异步任务,如果异步任务不支持远程调用,动态锁不会被释放,所以使用动态锁,
一定要将异步任务写成远程组件