Get the App
SLTechnology News&Howtos  ›  Development  › 

How to solve the problem of data insertion and repetition under java concurrent requests

Shulou Source: shulou.com Published: 2022-06-02 15:43:01 10月30日 Update

This article introduces the knowledge of "how to solve the problem of data insertion and duplication under java concurrent requests". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Preface

Some time ago, it was found that there are often two same pieces of user data in the database, resulting in abnormal data query. Checked the reason, found that the front-end WeChat Mini Programs authorized login, sometimes sent two identical requests at the same time (that is, often said concurrency). Although the back-end code can prevent repetition, it can not avoid repetitive operations when concurrency occurs. So we start thinking about concurrency solutions, and there are many solutions, from intercepting requests to the database level.

We adopt the scheme of generating summary information and Redis distributed lock for the request message. After running for a period of time, the function is very reliable and the code is very concise. So I came up to make a record for follow-up reference.

Solution description:

The Spring boot used in the system architecture defines a Filter filter to filter the request, then generates summary information for the request message and sets the Redis distributed lock. Determine whether it is the same request by summary and lock.

Distributed lock tool class public class ContextLJ {private static final Integer JD = 0 / * * Lock using redis to lock distributed projects * @ param sign * @ param tiD * @ return * @ throws Exception * / public static boolean lock (String sign String tiD) {synchronized (JD) {/ / locked Cache cache = CacheManager.getCommonCache (sign) If (cache = = null | | StringUtils.isBlank (cache.getValue () {CacheManager.putCommonCacheInfo (sign, tiD, 10000); return true;} return false }} / * * Lock verification * @ param sign * @ param tiD * @ return * / public static boolean checklock (String sign, String tiD) {Cache cache = CacheManager.getCommonCache (sign) String uTid = StringUtils.replace (cache.getValue (), "\", "); return tiD.equals (uTid) } / * * remove the lock * @ param sign * @ param tiD * / public static void clent (String sign, String tiD) {if (checklock (sign, tiD)) {CacheManager.clearOnly (sign) }} / * get summary * @ param request * / public static String getSign (ServletRequest request) {/ / this tool assembles the request content in request into the form of key=value&key=value2 source code on the line String sign = null Try {Map map = getRequstMap ((HttpServletRequest) request); / / generate summary sign = buildRequest (map);} catch (Exception e) {e.printStackTrace ();} return sign } public static Map getRequstMap (HttpServletRequest req) throws Exception {Map params = new HashMap (); params.put ("uri", req.getRequestURI ()); Map requestParams = req.getParameterMap (); for (Iterator iter = requestParams.keySet (). Iterator (); iter.hasNext () ) {String name = (String) iter.next (); String [] values = (String []) requestParams.get (name); String valueStr = ""; for (int I = 0; I < values.length; ionization +) {valueStr = (I = = values.length-1)? ValueStr + values [I]: valueStr + values [I] + ",";} params.put (name, valueStr);} return params;} private static String buildRequest (Map map) {List signList = new ArrayList () For (Entry entry: map.entrySet ()) {signList.add (entry.getKey () + "=" + entry.getValue ());} String sign = StringUtils.join (signList, "&"); return DigestUtils.md5Hex (sign) }} implement request interception in filter / * filter frequent requests * / @ Slf4j@Componentpublic class MyFilter implements Filter {@ Override public void init (FilterConfig filterConfig) throws ServletException {} @ Override public void doFilter (ServletRequest request, ServletResponse myResp, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request Boolean isDict = StringUtils.contains (req.getRequestURI (), "/ dict/getDatas"); Boolean isFile = StringUtils.contains (req.getRequestURI (), "/ files/file"); if (isDict | | isFile) {chain.doFilter (request, myResp); / / query data dictionary or file, and release return directly } String sign = "sign_" + ContextLJ.getSign (request); / / generate summary String tiD = RandomUtils.randomCode (3) + "_" + Thread.currentThread () .getId () / / current thread identity try {if (! ContextLJ.lock (sign, tiD)) {Map map = ContextLJ.getRequstMap ((HttpServletRequest) request); log.warn ("abandon the same concurrent request [" + sign+ "] [" + tiD+ "]" + JSON.toJSONString (map) FrequentlyError (myResp); return;} if (! ContextLJ.checklock (sign, tiD)) {Map map = ContextLJ.getRequstMap ((HttpServletRequest) request) Log.warn ("lock verification failed [" + sign+ "] [" + tiD+ "]" + JSON.toJSONString (map)); frequentlyError (myResp); return;} chain.doFilter (request, myResp) / / release} catch (Exception e) {/ / catch exception for exception filtering log.error (", e); myResp.getWriter () .write (ApiRs.asError (" server is busy, please try again "));} finally {ContextLJ.clent (sign, tiD) } @ Override public void destroy () {} / * * frequent requests * / private void frequentlyError (ServletResponse myResp) throws IOException {((HttpServletResponse) myResp) .setHeader ("Content-type", "text/html;charset=UTF-8") MyResp.getWriter (). Write (JSON.toJSONString (ApiRs.asError);}} "how to solve the problem of data insertion and duplication under java concurrent requests" is here. Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Tags: Data summary distributed scheme generation frequency content solution problem same code information tools message database time more knowledge filter query Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno Shulou Tech Info vpn Redmi Docker Huawei