解决的问题
分布式环境下,希望把用户的操作从并发执行变成原子执行案例:
将订单并发变成串行执行, 相比悲观锁来说能够减少数据库的压力。
原理
redis是单线程的,并发过来的请求,redis都会让他们排队串行执行,redis内部是线程安全的
实现的代码
<ignore_js_op>
考虑到如果下单出现异常则锁将永远无法释放,因此做异常捕获,无论代码是否异常要释放锁
<ignore_js_op>
考虑到如果下单过程中服务器宕机,则锁将永远无法释放
方案一:应用开始起置空redis中的lock
方案二:给锁设置过期时间,但是如果用户的下单操作超过了lock的过期时间,则下单没有完成锁就失效了。 过期时间设置的太长宕机立刻重启问题也解决不了
# 解决方案 启动一个子线程,每过2s给锁重设过期时间,主线程执行结束,则销毁子线程
<ignore_js_op>
销毁线程的代码
[Python]
纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
from
threading
import
Thread
import
inspect
import
ctypes
def
_async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid
=
ctypes.c_long(tid)
if
not
inspect.isclass(exctype):
exctype
=
type
(exctype)
res
=
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if
res
=
=
0
:
raise
ValueError(
"invalid thread id"
)
elif
res !
=
1
:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
None
)
raise
SystemError(
"PyThreadState_SetAsyncExc failed"
)
def
stop_thread(thread):
_async_raise(thread.ident, SystemExit)
def
a():
while
True
:
print
(
"123456789"
)
if
__name__
=
=
'__main__'
:
t
=
Thread(target
=
a)
t.start()
stop_thread(t)
|
遗留的问题 下单不符合先来后到的顺序
更多技术资讯可关注:gzitcast