diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java index 19e9e6ffb..fa8ad673b 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java @@ -1,17 +1,21 @@ package ru.spcex.clearing.backendapi.service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.user.ClearingUser; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.log.ExceptionUtils; import java.time.Instant; import java.util.Map; @Service public class UserAutoCreateService { + private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg userMap; @@ -22,15 +26,20 @@ public class UserAutoCreateService { /** * при необходимости переделать на отдельный поток - * todo transactional? */ public void createUserIfNeeded(String userName) { - ClearingUser username = userMap.getSingleObjectByFieldValues(Map.of("username", userName)); - if (username == null) { - username = new ClearingUser(); - username.setUsername(userName); - username.setCreated(Instant.now()); - userMap.insert(username); - } + userMap.lockAndPerform(() -> { + try { + ClearingUser username = userMap.getSingleObjectByFieldValues(Map.of("username", userName)); + if (username == null) { + username = new ClearingUser(); + username.setUsername(userName); + username.setCreated(Instant.now()); + userMap.insert(username); + } + } catch (Throwable e) { + log.error(ExceptionUtils.getStackTrace(e)); + } + }); } } diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java index ab51b6132..c1e19049e 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java @@ -1,33 +1,27 @@ package ru.spcex.platform.imdg.iml.hazelcast.adapter; +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.core.ILock; import com.hazelcast.core.IMap; import com.hazelcast.core.IdGenerator; import com.hazelcast.query.Predicate; import com.hazelcast.query.Predicates; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.utils.log.ExceptionUtils; import java.util.*; public class ImdgHazelcast implements Imdg { + private final Logger log = LoggerFactory.getLogger(getClass()); private IdGenerator idGenerator; private IMap map; - public IMap getMap() { - return map; - } + private String mapName; - public void setMap(IMap map) { - this.map = map; - } - - public IdGenerator getIdGenerator() { - return idGenerator; - } - - public void setIdGenerator(IdGenerator idGenerator) { - this.idGenerator = idGenerator; - } + private HazelcastInstance hzInstance; @Override public void insert(T paramT) { @@ -35,6 +29,25 @@ public class ImdgHazelcast implements Imdg { map.put(paramT.getId(), paramT); } + @Override + public void lockAndPerform(Runnable operation) { + ILock hzLock = null; + try { + //в качестве альтернативы getCPSubsystem, поддерживается только при 3+ нодах хазелкаста + hzLock = hzInstance.getLock(mapName); + hzLock.lock(); + operation.run(); + } finally { + if (hzLock != null) { + try { + hzLock.unlock(); + } catch (Throwable e) { + log.error("{} {}", mapName, ExceptionUtils.getStackTrace(e)); + } + } + } + } + @Override public void update(T paramT) { map.put(paramT.getId(), paramT); @@ -97,4 +110,36 @@ public class ImdgHazelcast implements Imdg { } return searchResult; } + + public IMap getMap() { + return map; + } + + public void setMap(IMap map) { + this.map = map; + } + + public IdGenerator getIdGenerator() { + return idGenerator; + } + + public void setIdGenerator(IdGenerator idGenerator) { + this.idGenerator = idGenerator; + } + + public HazelcastInstance getHzInstance() { + return hzInstance; + } + + public void setHzInstance(HazelcastInstance hzInstance) { + this.hzInstance = hzInstance; + } + + public String getMapName() { + return mapName; + } + + public void setMapName(String mapName) { + this.mapName = mapName; + } } diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java index f6d80b3ff..dcf70320b 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java @@ -223,6 +223,8 @@ public abstract class HazelcastServiceBase public void getAvailable(HazelcastInstance hazelcastNotInited) { IdGenerator generator = hazelcastInstance.getIdGenerator(IMDGDistributedNames.MAP_SEQUENCE_NAME); imdg.setMap(hazelcastInstance.getMap(key)); + imdg.setMapName(key); + imdg.setHzInstance(hazelcastInstance); imdg.setIdGenerator(generator); } diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java index 49b9ddf94..845eeb86f 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java @@ -10,6 +10,10 @@ public interface Imdg { throw new UnsupportedOperationException("not implemented insert"); } + default void lockAndPerform(Runnable operation) { + throw new UnsupportedOperationException("not implemented lockAndPerform"); + } + default void update(T paramT) { throw new UnsupportedOperationException("not implemented update"); }