Skip to content

Commit

Permalink
实现全局锁在mongodb下的持久化, 完善 MongodbRepository 的相关方法, 并编写相关测试用例; 修改RedisRep…
Browse files Browse the repository at this point in the history
…ository的releaseHmilyLocks()方法的返回值 (#360)
  • Loading branch information
zkyoma authored and cherrylzhao committed Oct 24, 2023
1 parent 334d863 commit db6faa0
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.dromara.hmily.repository.mongodb;

import org.dromara.hmily.repository.mongodb.entity.LockMongoEntity;
import org.dromara.hmily.repository.mongodb.entity.ParticipantMongoEntity;
import org.dromara.hmily.repository.mongodb.entity.TransactionMongoEntity;
import org.dromara.hmily.repository.mongodb.entity.UndoMongoEntity;
import org.dromara.hmily.repository.spi.entity.HmilyDataSnapshot;
import org.dromara.hmily.repository.spi.entity.HmilyInvocation;
import org.dromara.hmily.repository.spi.entity.HmilyLock;
import org.dromara.hmily.repository.spi.entity.HmilyParticipant;
import org.dromara.hmily.repository.spi.entity.HmilyParticipantUndo;
import org.dromara.hmily.repository.spi.entity.HmilyTransaction;
Expand Down Expand Up @@ -107,6 +109,16 @@ public HmilyParticipantUndo convert(final UndoMongoEntity entity) {
return undo;
}

/**
* 转换mongo对象.
* @param entity mongo entity.
* @return hmily entity.
*/
public HmilyLock convert(final LockMongoEntity entity) {
return new HmilyLock(entity.getTransId(), entity.getParticipantId(), entity.getResourceId(),
entity.getTargetTableName(), entity.getTargetTablePk());
}

/**
* 转换mongo对象.
* @param hmilyParticipant hmilyParticipant entity.
Expand Down Expand Up @@ -179,4 +191,20 @@ public UndoMongoEntity create(final HmilyParticipantUndo undo) {
entity.setUpdateTime(undo.getUpdateTime());
return entity;
}

/**
* 转换mongo对象.
* @param lock hmily entity.
* @return mongo entity.
*/
public LockMongoEntity create(final HmilyLock lock) {
LockMongoEntity entity = new LockMongoEntity();
entity.setLockId(lock.getLockId());
entity.setTargetTableName(lock.getTargetTableName());
entity.setTargetTablePk(lock.getTargetTablePk());
entity.setResourceId(lock.getResourceId());
entity.setParticipantId(lock.getParticipantId());
entity.setTransId(lock.getTransId());
return entity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.lang3.tuple.Pair;
import org.dromara.hmily.config.api.ConfigEnv;
import org.dromara.hmily.config.api.entity.HmilyMongoConfig;
import org.dromara.hmily.repository.mongodb.entity.LockMongoEntity;
import org.dromara.hmily.repository.mongodb.entity.ParticipantMongoEntity;
import org.dromara.hmily.repository.mongodb.entity.TransactionMongoEntity;
import org.dromara.hmily.repository.mongodb.entity.UndoMongoEntity;
Expand All @@ -38,6 +39,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.net.InetSocketAddress;
import java.util.ArrayList;
Expand Down Expand Up @@ -210,20 +212,34 @@ public int updateHmilyParticipantUndoStatus(final Long undoId, final Integer sta

@Override
public int writeHmilyLocks(final Collection<HmilyLock> locks) {
// TODO
return 0;
int cnt = 0;
for (HmilyLock lock : locks) {
Query query = new Query();
query.addCriteria(Criteria.where("lock_id").is(lock.getLockId()));
boolean exists = service.exists(query, LockMongoEntity.class);
if (!exists) {
cnt++;
if (FAIL_ROWS == service.insertc(converter.create(lock))) {
return FAIL_ROWS;
}
}
}
return cnt;
}

@Override
public int releaseHmilyLocks(final Collection<HmilyLock> locks) {
// TODO
return 0;
int cnt = 0;
for (HmilyLock lock : locks) {
cnt += service.delete(LockMongoEntity.class, Criteria.where("lock_id").is(lock.getLockId()));
}
return cnt;
}

@Override
public Optional<HmilyLock> findHmilyLockById(final String lockId) {
// TODO
return Optional.empty();
return service.find(LockMongoEntity.class, Criteria.where("lock_id").is(lockId))
.stream().map(converter::convert).findFirst();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.dromara.hmily.repository.mongodb.entity;

import lombok.Data;
import lombok.ToString;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;


/**
* mongo entity.
*
* @author gcedar
*/
@Data
@ToString
@Document(collection = "hmily_lock_global")
public class LockMongoEntity {

@Field("lock_id")
@Indexed
private String lockId;

@Field("trans_id")
private Long transId;

@Field("participant_id")
private Long participantId;

@Field("resource_id")
private String resourceId;

@Field("target_table_Name")
private String targetTableName;

@Field("target_table_pk")
private String targetTablePk;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package org.dromara.hmily.repository.mongodb;

import org.dromara.hmily.config.api.ConfigEnv;
import org.dromara.hmily.config.api.entity.HmilyMongoConfig;
import org.dromara.hmily.repository.spi.HmilyRepository;
import org.dromara.hmily.repository.spi.entity.HmilyLock;
import org.dromara.hmily.serializer.spi.HmilySerializer;
import org.dromara.hmily.serializer.spi.exception.HmilySerializerException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.util.*;

/**
* @Author zhangzhi
* @Date: 2023/8/9 13:33
*/
public class MongodbRepositoryTest {

private MongodbRepository mongodbRepository;

private final Random random = new Random(System.currentTimeMillis());
private final List<HmilyLock> locks = new ArrayList<>();

@Before
public void setup() {
Long transId = (long) random.nextInt(1000);
Long participantId = (long) random.nextInt(1000);
String resourceId = "jdbc:mysql://localhost:3306/test";
for (int i = 1; i <= 5; i++) {
HmilyLock lock = new HmilyLock(transId, participantId, resourceId, "tableName" + i, i + "");
locks.add(lock);
}
registerConfig();
mongodbRepository = new MongodbRepository();
mongodbRepository.setSerializer(new HmilySerializer() {
@Override
public byte[] serialize(final Object obj) throws HmilySerializerException {
try (ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); ObjectOutput objectOutput = new ObjectOutputStream(arrayOutputStream)) {
objectOutput.writeObject(obj);
objectOutput.flush();
return arrayOutputStream.toByteArray();
} catch (IOException e) {
throw new HmilySerializerException("java serialize error " + e.getMessage());
}
}

@Override
@SuppressWarnings("unchecked")
public <T> T deSerialize(final byte[] param, final Class<T> clazz) throws HmilySerializerException {
try (ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(param); ObjectInput input = new ObjectInputStream(arrayInputStream)) {
return (T) input.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new HmilySerializerException("java deSerialize error " + e.getMessage());
}
}
});
mongodbRepository.init("appName");
}

@Test
public void testWriteHmilyLocks() {
int rows = mongodbRepository.writeHmilyLocks(locks);
Assert.assertEquals(locks.size(), rows);
}

@Test
public void testReleaseHmilyLocks() {
int rows = mongodbRepository.releaseHmilyLocks(locks);
Assert.assertEquals(locks.size(), rows);
}

@Test
public void testFindHmilyLockById() {
mongodbRepository.writeHmilyLocks(locks);
// 锁不存在
mongodbRepository.releaseHmilyLocks(locks);
String lockId = locks.get(0).getLockId();
Optional<HmilyLock> lockOptional = mongodbRepository.findHmilyLockById(lockId);
Assert.assertEquals(Optional.empty(), lockOptional);

// 锁存在
mongodbRepository.writeHmilyLocks(locks);
lockId = locks.get(0).getLockId();
lockOptional = mongodbRepository.findHmilyLockById(lockId);
Assert.assertEquals(lockId, lockOptional.get().getLockId());
}

private void registerConfig() {
HmilyMongoConfig mongoConfig = new HmilyMongoConfig();
mongoConfig.setUrl("localhost:27017");
mongoConfig.setDatabaseName("hmily");
mongoConfig.setUserName("test");
mongoConfig.setPassword("test");
ConfigEnv.getInstance().registerConfig(mongoConfig);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
log4j.rootLogger=INFO,CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[frame] %d{yyyy-MM-dd HH:mm:ss,SSS} - %-4r %-5p [%t] %C:%L %x - %m%n
Original file line number Diff line number Diff line change
Expand Up @@ -450,11 +450,13 @@ public int writeHmilyLocks(final Collection<HmilyLock> locks) {

@Override
public int releaseHmilyLocks(final Collection<HmilyLock> locks) {
int cnt = 0;
try {
for (HmilyLock lock : locks) {
jedisClient.hdel(HMILY_LOCK_GLOBAL, lock.getLockId());
cnt++;
}
return HmilyRepository.ROWS;
return cnt;
} catch (JedisException e) {
LOGGER.error("releaseHmilyLocks occur a exception", e);
}
Expand Down

0 comments on commit db6faa0

Please sign in to comment.