Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
Litemall
Commits
e95948bf
Commit
e95948bf
authored
Sep 18, 2019
by
朱洪锦
Browse files
通过延时队列实现检查订单是否已经超期,自动取消订单的功能
parent
3ad47b5b
Changes
4
Hide whitespace changes
Inline
Side-by-side
litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/OrderJob.java
View file @
e95948bf
...
...
@@ -40,33 +40,33 @@ public class OrderJob {
* TODO
* 注意,因为是相隔半小时检查,因此导致订单真正超时时间是 [LITEMALL_ORDER_UNPAID, 30 + LITEMALL_ORDER_UNPAID]
*/
@Scheduled
(
fixedDelay
=
30
*
60
*
1000
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
void
checkOrderUnpaid
()
{
logger
.
info
(
"系统开启任务检查订单是否已经超期自动取消订单"
);
List
<
LitemallOrder
>
orderList
=
orderService
.
queryUnpaid
(
SystemConfig
.
getOrderUnpaid
());
for
(
LitemallOrder
order
:
orderList
)
{
// 设置订单已取消状态
order
.
setOrderStatus
(
OrderUtil
.
STATUS_AUTO_CANCEL
);
order
.
setEndTime
(
LocalDateTime
.
now
());
if
(
orderService
.
updateWithOptimisticLocker
(
order
)
==
0
)
{
throw
new
RuntimeException
(
"更新数据已失效"
);
}
// 商品货品数量增加
Integer
orderId
=
order
.
getId
();
List
<
LitemallOrderGoods
>
orderGoodsList
=
orderGoodsService
.
queryByOid
(
orderId
);
for
(
LitemallOrderGoods
orderGoods
:
orderGoodsList
)
{
Integer
productId
=
orderGoods
.
getProductId
();
Short
number
=
orderGoods
.
getNumber
();
if
(
productService
.
addStock
(
productId
,
number
)
==
0
)
{
throw
new
RuntimeException
(
"商品货品库存增加失败"
);
}
}
logger
.
info
(
"订单 ID"
+
order
.
getId
()
+
" 已经超期自动取消订单"
);
}
}
//
@Scheduled(fixedDelay = 30 * 60 * 1000)
//
@Transactional(rollbackFor = Exception.class)
//
public void checkOrderUnpaid() {
//
logger.info("系统开启任务检查订单是否已经超期自动取消订单");
//
//
List<LitemallOrder> orderList = orderService.queryUnpaid(SystemConfig.getOrderUnpaid());
//
for (LitemallOrder order : orderList) {
//
// 设置订单已取消状态
//
order.setOrderStatus(OrderUtil.STATUS_AUTO_CANCEL);
//
order.setEndTime(LocalDateTime.now());
//
if (orderService.updateWithOptimisticLocker(order) == 0) {
//
throw new RuntimeException("更新数据已失效");
//
}
//
//
// 商品货品数量增加
//
Integer orderId = order.getId();
//
List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
//
for (LitemallOrderGoods orderGoods : orderGoodsList) {
//
Integer productId = orderGoods.getProductId();
//
Short number = orderGoods.getNumber();
//
if (productService.addStock(productId, number) == 0) {
//
throw new RuntimeException("商品货品库存增加失败");
//
}
//
}
//
logger.info("订单 ID" + order.getId() + " 已经超期自动取消订单");
//
}
//
}
/**
* 自动确认订单
...
...
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallOrderService.java
View file @
e95948bf
...
...
@@ -5,6 +5,7 @@ import org.linlinjava.litemall.db.dao.LitemallOrderMapper;
import
org.linlinjava.litemall.db.dao.OrderMapper
;
import
org.linlinjava.litemall.db.domain.LitemallOrder
;
import
org.linlinjava.litemall.db.domain.LitemallOrderExample
;
import
org.linlinjava.litemall.db.task.OrderDelayedTaskManager
;
import
org.linlinjava.litemall.db.util.OrderUtil
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.StringUtils
;
...
...
@@ -28,6 +29,8 @@ public class LitemallOrderService {
public
int
add
(
LitemallOrder
order
)
{
order
.
setAddTime
(
LocalDateTime
.
now
());
order
.
setUpdateTime
(
LocalDateTime
.
now
());
OrderDelayedTaskManager
manager
=
OrderDelayedTaskManager
.
getInstance
();
manager
.
putQueue
(
order
);
return
litemallOrderMapper
.
insertSelective
(
order
);
}
...
...
litemall-db/src/main/java/org/linlinjava/litemall/db/task/OrderDelayedTask.java
0 → 100644
View file @
e95948bf
package
org.linlinjava.litemall.db.task
;
import
org.linlinjava.litemall.db.domain.LitemallOrder
;
import
java.time.ZoneOffset
;
import
java.util.concurrent.Delayed
;
import
java.util.concurrent.TimeUnit
;
public
class
OrderDelayedTask
implements
Delayed
{
private
LitemallOrder
order
;
/**
* 延时时间 单位 timeunit.milliseconds
**/
private
long
timeout
;
private
long
exprire
;
public
OrderDelayedTask
(
LitemallOrder
order
,
long
timeout
)
{
this
.
order
=
order
;
this
.
timeout
=
timeout
;
this
.
exprire
=
order
.
getAddTime
().
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
()
+
timeout
;
}
public
LitemallOrder
getOrder
()
{
return
order
;
}
@Override
public
long
getDelay
(
TimeUnit
unit
)
{
return
unit
.
convert
(
exprire
-
System
.
currentTimeMillis
(),
TimeUnit
.
MILLISECONDS
);
}
@Override
public
int
compareTo
(
Delayed
o
)
{
OrderDelayedTask
other
=
(
OrderDelayedTask
)
o
;
long
diff
=
order
.
getAddTime
().
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
()
-
other
.
getOrder
().
getAddTime
().
toInstant
(
ZoneOffset
.
of
(
"+8"
)).
toEpochMilli
();
if
(
diff
>
0
)
{
return
1
;
}
else
if
(
diff
<
0
)
{
return
-
1
;
}
else
{
return
0
;
}
}
@Override
public
String
toString
()
{
return
"OrderDelayedTask{"
+
"order="
+
order
+
", timeout="
+
timeout
+
'}'
;
}
}
litemall-db/src/main/java/org/linlinjava/litemall/db/task/OrderDelayedTaskManager.java
0 → 100644
View file @
e95948bf
package
org.linlinjava.litemall.db.task
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.linlinjava.litemall.db.domain.LitemallOrder
;
import
org.linlinjava.litemall.db.domain.LitemallOrderGoods
;
import
org.linlinjava.litemall.db.service.LitemallGoodsProductService
;
import
org.linlinjava.litemall.db.service.LitemallOrderGoodsService
;
import
org.linlinjava.litemall.db.service.LitemallOrderService
;
import
org.linlinjava.litemall.db.util.OrderUtil
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.time.LocalDateTime
;
import
java.util.List
;
import
java.util.concurrent.DelayQueue
;
import
java.util.concurrent.TimeUnit
;
@Component
public
class
OrderDelayedTaskManager
{
private
static
final
Log
log
=
LogFactory
.
getLog
(
OrderDelayedTaskManager
.
class
);
@Autowired
private
LitemallOrderGoodsService
orderGoodsService
;
@Autowired
private
LitemallOrderService
orderService
;
@Autowired
private
LitemallGoodsProductService
productService
;
private
DelayQueue
<
OrderDelayedTask
>
queue
;
// 守护线程
private
Thread
daemonThread
;
private
static
OrderDelayedTaskManager
instance
=
new
OrderDelayedTaskManager
();
private
OrderDelayedTaskManager
()
{
queue
=
new
DelayQueue
<>();
init
();
}
public
static
OrderDelayedTaskManager
getInstance
()
{
return
instance
;
}
/**
* 初始化
*/
public
void
init
()
{
daemonThread
=
new
Thread
(()
->
execute
());
daemonThread
.
setName
(
"DelayQueueMonitor"
);
daemonThread
.
start
();
}
public
void
execute
()
{
while
(
true
)
{
log
.
info
(
"当前延时队列的任务数量:"
+
queue
.
size
());
try
{
OrderDelayedTask
task
=
queue
.
take
();
if
(
null
!=
task
)
{
LitemallOrder
order
=
task
.
getOrder
();
if
(
null
==
order
)
{
continue
;
}
// 设置订单已取消状态
order
.
setOrderStatus
(
OrderUtil
.
STATUS_AUTO_CANCEL
);
order
.
setEndTime
(
LocalDateTime
.
now
());
if
(
orderService
.
updateWithOptimisticLocker
(
order
)
==
0
)
{
throw
new
RuntimeException
(
"更新数据已失效"
);
}
// 商品货品数量增加
Integer
orderId
=
order
.
getId
();
List
<
LitemallOrderGoods
>
orderGoodsList
=
orderGoodsService
.
queryByOid
(
orderId
);
for
(
LitemallOrderGoods
orderGoods
:
orderGoodsList
)
{
Integer
productId
=
orderGoods
.
getProductId
();
Short
number
=
orderGoods
.
getNumber
();
if
(
productService
.
addStock
(
productId
,
number
)
==
0
)
{
throw
new
RuntimeException
(
"商品货品库存增加失败"
);
}
}
log
.
info
(
"订单 ID"
+
order
.
getId
()
+
" 已经超期自动取消订单"
);
log
.
info
(
"end:"
+
LocalDateTime
.
now
());
}
}
catch
(
InterruptedException
e
)
{
log
.
error
(
"获取延时任务失败!"
,
e
);
}
}
}
public
void
putQueue
(
LitemallOrder
order
)
{
OrderDelayedTask
task
=
new
OrderDelayedTask
(
order
,
TimeUnit
.
MINUTES
.
toMillis
(
30
));
queue
.
put
(
task
);
}
public
void
removeQueue
(
OrderDelayedTask
task
)
{
queue
.
remove
(
task
);
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment