Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
xyqb-user2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
head_group
xyqb-user2
Commits
18ad952c
Commit
18ad952c
authored
Mar 03, 2020
by
杨锐
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
redis分布式锁,处理/user/login/fast并发问题,导致MySQLIntegrityConstraintViolationException
parent
9ca25373
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
82 additions
and
33 deletions
+82
-33
UserController.java
...n/quantgroup/xyqb/controller/external/UserController.java
+1
-20
IUserService.java
...in/java/cn/quantgroup/xyqb/service/user/IUserService.java
+7
-0
UserServiceImpl.java
...cn/quantgroup/xyqb/service/user/impl/UserServiceImpl.java
+74
-13
No files found.
src/main/java/cn/quantgroup/xyqb/controller/external/UserController.java
View file @
18ad952c
...
@@ -27,7 +27,6 @@ import cn.quantgroup.xyqb.service.user.UserCenterService;
...
@@ -27,7 +27,6 @@ import cn.quantgroup.xyqb.service.user.UserCenterService;
import
cn.quantgroup.xyqb.service.wechat.IWechatService
;
import
cn.quantgroup.xyqb.service.wechat.IWechatService
;
import
cn.quantgroup.xyqb.session.XyqbSessionContextHolder
;
import
cn.quantgroup.xyqb.session.XyqbSessionContextHolder
;
import
cn.quantgroup.xyqb.util.IpUtil
;
import
cn.quantgroup.xyqb.util.IpUtil
;
import
cn.quantgroup.xyqb.util.MqUtils
;
import
cn.quantgroup.xyqb.util.PasswordUtil
;
import
cn.quantgroup.xyqb.util.PasswordUtil
;
import
cn.quantgroup.xyqb.util.ValidationUtil
;
import
cn.quantgroup.xyqb.util.ValidationUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSON
;
...
@@ -185,25 +184,7 @@ public class UserController implements IBaseController {
...
@@ -185,25 +184,7 @@ public class UserController implements IBaseController {
String
verificationCode
=
successResult
.
getMsg
();
String
verificationCode
=
successResult
.
getMsg
();
// 执行短信验证码检查
// 执行短信验证码检查
verifyPhoneAndCode
(
phoneNo
,
verificationCode
);
verifyPhoneAndCode
(
phoneNo
,
verificationCode
);
User
user
=
userService
.
findByPhoneWithCache
(
phoneNo
);
return
userService
.
loginFast
(
channelId
,
appChannel
,
createdFrom
,
btRegisterChannelId
,
dimension
,
clickId
,
request
,
merchant
,
phoneNo
);
if
(
user
!=
null
&&
!
user
.
getEnable
())
{
log
.
info
(
"用户不存在,或者已经注销,phoneNo:{}"
,
phoneNo
);
return
JsonResult
.
buildErrorStateResult
(
"登录失败"
,
null
);
}
if
(
user
==
null
)
{
// Service层会负责发送注册消息到LoanVest
user
=
userRegisterService
.
register
(
phoneNo
,
channelId
,
createdFrom
,
appChannel
,
btRegisterChannelId
,
dimension
);
if
(
user
==
null
)
{
throw
new
UserNotExistException
(
"用户未找到"
);
}
//广点通转化注册 - 发送消息 - 方法内过滤
MqUtils
.
sendRegisterMessageForGdt
(
phoneNo
,
clickId
);
}
if
(!
wechatRelateUserIfNecessary
(
user
,
request
))
{
return
JsonResult
.
buildErrorStateResult
(
"登录时微信关联失败"
,
null
);
}
LoginProperties
loginProperties
=
new
LoginProperties
(
""
,
3
,
channelId
,
createdFrom
,
appChannel
,
merchant
.
getId
(),
merchant
.
getName
());
return
new
JsonResult
(
sessionService
.
createSession
(
user
,
loginProperties
));
}
}
/**
/**
...
...
src/main/java/cn/quantgroup/xyqb/service/user/IUserService.java
View file @
18ad952c
package
cn
.
quantgroup
.
xyqb
.
service
.
user
;
package
cn
.
quantgroup
.
xyqb
.
service
.
user
;
import
cn.quantgroup.xyqb.entity.Merchant
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.UserInfo
;
import
cn.quantgroup.xyqb.model.UserInfo
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
...
@@ -67,4 +70,8 @@ public interface IUserService {
...
@@ -67,4 +70,8 @@ public interface IUserService {
* @param phoneNo 根据手机号
* @param phoneNo 根据手机号
*/
*/
void
userCacheEvict
(
String
uuid
,
String
phoneNo
);
void
userCacheEvict
(
String
uuid
,
String
phoneNo
);
JsonResult
loginFast
(
Long
channelId
,
String
appChannel
,
Long
createdFrom
,
Long
btRegisterChannelId
,
String
dimension
,
String
clickId
,
HttpServletRequest
request
,
Merchant
merchant
,
String
phoneNo
);
}
}
src/main/java/cn/quantgroup/xyqb/service/user/impl/UserServiceImpl.java
View file @
18ad952c
...
@@ -2,22 +2,25 @@ package cn.quantgroup.xyqb.service.user.impl;
...
@@ -2,22 +2,25 @@ package cn.quantgroup.xyqb.service.user.impl;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.aspect.lock.RedisLock
;
import
cn.quantgroup.xyqb.aspect.lock.RedisLock
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.entity.UserDetail
;
import
cn.quantgroup.xyqb.entity.*
;
import
cn.quantgroup.xyqb.entity.UserHashMapping
;
import
cn.quantgroup.xyqb.entity.UserHashPhoneNoIdNoMapping
;
import
cn.quantgroup.xyqb.event.PhoneNoUpdateEvent
;
import
cn.quantgroup.xyqb.event.PhoneNoUpdateEvent
;
import
cn.quantgroup.xyqb.exception.DataException
;
import
cn.quantgroup.xyqb.exception.DataException
;
import
cn.quantgroup.xyqb.exception.UserNotExistException
;
import
cn.quantgroup.xyqb.model.FindByMd5Enum
;
import
cn.quantgroup.xyqb.model.FindByMd5Enum
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.LoginProperties
;
import
cn.quantgroup.xyqb.model.UserInfo
;
import
cn.quantgroup.xyqb.model.UserInfo
;
import
cn.quantgroup.xyqb.repository.IUserHashMappingRepository
;
import
cn.quantgroup.xyqb.repository.IUserHashMappingRepository
;
import
cn.quantgroup.xyqb.repository.IUserHashPhoneNoIdNoMappingRepository
;
import
cn.quantgroup.xyqb.repository.IUserHashPhoneNoIdNoMappingRepository
;
import
cn.quantgroup.xyqb.repository.IUserRepository
;
import
cn.quantgroup.xyqb.repository.IUserRepository
;
import
cn.quantgroup.xyqb.service.register.IUserRegisterService
;
import
cn.quantgroup.xyqb.service.session.ISessionService
;
import
cn.quantgroup.xyqb.service.user.IUserDetailService
;
import
cn.quantgroup.xyqb.service.user.IUserDetailService
;
import
cn.quantgroup.xyqb.service.user.IUserService
;
import
cn.quantgroup.xyqb.service.user.IUserService
;
import
cn.quantgroup.xyqb.
util.HashUtil
;
import
cn.quantgroup.xyqb.
service.wechat.IWechatService
;
import
cn.quantgroup.xyqb.util.
PasswordUtil
;
import
cn.quantgroup.xyqb.util.
*
;
import
c
n.quantgroup.xyqb.util.ValidationUtil
;
import
c
om.alibaba.fastjson.JSON
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Maps
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
...
@@ -33,11 +36,9 @@ import org.springframework.transaction.annotation.Transactional;
...
@@ -33,11 +36,9 @@ import org.springframework.transaction.annotation.Transactional;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.CollectionUtils
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
javax.servlet.http.HttpServletRequest
;
import
java.sql.Timestamp
;
import
java.sql.Timestamp
;
import
java.util.Collections
;
import
java.util.*
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
/**
/**
...
@@ -45,7 +46,7 @@ import java.util.concurrent.TimeUnit;
...
@@ -45,7 +46,7 @@ import java.util.concurrent.TimeUnit;
*/
*/
@Service
@Service
@Slf4j
@Slf4j
public
class
UserServiceImpl
implements
IUserService
{
public
class
UserServiceImpl
implements
IUserService
,
IBaseController
{
@Autowired
@Autowired
private
RedisTemplate
<
String
,
String
>
stringRedisTemplate
;
private
RedisTemplate
<
String
,
String
>
stringRedisTemplate
;
...
@@ -64,6 +65,14 @@ public class UserServiceImpl implements IUserService {
...
@@ -64,6 +65,14 @@ public class UserServiceImpl implements IUserService {
@Autowired
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
private
ApplicationEventPublisher
applicationEventPublisher
;
@Resource
private
IUserRegisterService
userRegisterService
;
@Autowired
private
IWechatService
wechatService
;
@Autowired
private
ISessionService
sessionService
;
@Override
@Override
@Cacheable
(
value
=
"usercache"
,
key
=
"'xyqbuser' + #phone"
,
unless
=
"#result == null"
,
cacheManager
=
"cacheManager"
)
@Cacheable
(
value
=
"usercache"
,
key
=
"'xyqbuser' + #phone"
,
unless
=
"#result == null"
,
cacheManager
=
"cacheManager"
)
...
@@ -120,7 +129,6 @@ public class UserServiceImpl implements IUserService {
...
@@ -120,7 +129,6 @@ public class UserServiceImpl implements IUserService {
}
}
@Override
@Override
@RedisLock
(
prefix
=
"lock:user:find:by:phone:"
,
key
=
"#this[0]"
)
@Cacheable
(
value
=
"usercache"
,
key
=
"'xyqbuser' + #phone"
,
unless
=
"#result == null"
,
cacheManager
=
"cacheManager"
)
@Cacheable
(
value
=
"usercache"
,
key
=
"'xyqbuser' + #phone"
,
unless
=
"#result == null"
,
cacheManager
=
"cacheManager"
)
public
User
findByPhoneWithCache
(
String
phone
)
{
public
User
findByPhoneWithCache
(
String
phone
)
{
return
userRepository
.
findByPhoneNo
(
phone
);
return
userRepository
.
findByPhoneNo
(
phone
);
...
@@ -263,4 +271,57 @@ public class UserServiceImpl implements IUserService {
...
@@ -263,4 +271,57 @@ public class UserServiceImpl implements IUserService {
log
.
info
(
"清理用户缓存成功,uuid:{},phoneNo:{}"
,
uuid
,
phoneNo
);
log
.
info
(
"清理用户缓存成功,uuid:{},phoneNo:{}"
,
uuid
,
phoneNo
);
}
}
@Override
@RedisLock
(
prefix
=
"lock:login:fast:"
,
key
=
"#this[8]"
)
public
JsonResult
loginFast
(
Long
channelId
,
String
appChannel
,
Long
createdFrom
,
Long
btRegisterChannelId
,
String
dimension
,
String
clickId
,
HttpServletRequest
request
,
Merchant
merchant
,
String
phoneNo
)
{
User
user
=
findByPhoneWithCache
(
phoneNo
);
if
(
user
!=
null
&&
!
user
.
getEnable
())
{
log
.
info
(
"用户不存在,或者已经注销,phoneNo:{}"
,
phoneNo
);
return
JsonResult
.
buildErrorStateResult
(
"登录失败"
,
null
);
}
if
(
user
==
null
)
{
// Service层会负责发送注册消息到LoanVest
user
=
userRegisterService
.
register
(
phoneNo
,
channelId
,
createdFrom
,
appChannel
,
btRegisterChannelId
,
dimension
);
if
(
user
==
null
)
{
throw
new
UserNotExistException
(
"用户未找到"
);
}
//广点通转化注册 - 发送消息 - 方法内过滤
MqUtils
.
sendRegisterMessageForGdt
(
phoneNo
,
clickId
);
}
if
(!
wechatRelateUserIfNecessary
(
user
,
request
))
{
return
JsonResult
.
buildErrorStateResult
(
"登录时微信关联失败"
,
null
);
}
LoginProperties
loginProperties
=
new
LoginProperties
(
""
,
3
,
channelId
,
createdFrom
,
appChannel
,
merchant
.
getId
(),
merchant
.
getName
());
return
new
JsonResult
(
sessionService
.
createSession
(
user
,
loginProperties
));
}
/**
* 如果必要的话,关联用户和微信
*
* @param user - 用户标识
* @param request - 当前请求
* @return true - 继续登录,false - 微信关联失败,重新登录
*/
private
boolean
wechatRelateUserIfNecessary
(
User
user
,
HttpServletRequest
request
)
{
Objects
.
requireNonNull
(
request
,
"无效请求"
);
String
clientIp
=
IpUtil
.
getRemoteIP
(
request
);
Set
<
String
>
paramKeys
=
request
.
getParameterMap
().
keySet
();
boolean
ready
=
paramKeys
.
contains
(
Constants
.
WECHAT_OPEN_ID
);
if
(!
ready
)
{
return
true
;
}
else
if
(
Objects
.
isNull
(
user
)
||
Objects
.
isNull
(
user
.
getId
())
||
StringUtils
.
isBlank
(
request
.
getParameter
(
Constants
.
WECHAT_OPEN_ID
)))
{
log
.
warn
(
"微信关联失败,user:{}, request-Header:{}"
,
user
,
JSON
.
toJSONString
(
getRequestHeaderMap
(
request
)));
return
false
;
}
Long
userId
=
user
.
getId
();
String
phoneNo
=
user
.
getPhoneNo
();
try
{
int
rows
=
wechatService
.
relateUser
(
userId
,
phoneNo
,
request
.
getParameter
(
Constants
.
WECHAT_OPEN_ID
));
return
rows
>
0
;
}
catch
(
Exception
e
)
{
log
.
error
(
"微信关联失败,user:{}, request-Header:{}"
,
user
,
JSON
.
toJSONString
(
getRequestHeaderMap
(
request
)),
e
);
}
return
false
;
}
}
}
Write
Preview
Markdown
is supported
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