英文:
AWS DynamoDB Partition Key Lock Implementation in Java
问题
以下是您提供的内容的翻译部分:
@Component
public class AwsDynamoDBConfiguration {
Logger logger = LoggerFactory.getLogger(AwsDynamoDBConfiguration.class);
/**
* AWS 配置。
*/
@Autowired
private AwsConfiguration awsConfiguration;
private static final AwsClientBuilder.EndpointConfiguration DYNAMODB_ENDPOINT = new AwsClientBuilder.EndpointConfiguration(
"https://dynamodb.us-east-1.amazonaws.com", "us-east-1");
private Optional<LockItem> lockItem;
private AmazonDynamoDBLockClient client;
public boolean lockDynamoDB() throws InterruptedException, IOException {
logger.info("开始:AWS DynamoDB lockDynamoDB");
boolean isDynamoDBLockAccessed = false;
final AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.standard()
.withEndpointConfiguration(DYNAMODB_ENDPOINT)
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("access_key", "secret_key")))
.build();
logger.info("已创建 DynamoDB。");
// 是否创建心跳后台线程
final boolean createHeartbeatBackgroundThread = true;
// 构建锁客户端
client = new AmazonDynamoDBLockClient(AmazonDynamoDBLockClientOptions.builder(dynamoDB, "tbl_test_lock")
.withTimeUnit(TimeUnit.SECONDS).withLeaseDuration(100L).withHeartbeatPeriod(3L)
.withCreateHeartbeatBackgroundThread(createHeartbeatBackgroundThread).build());
logger.info("已创建 DynamoDB 客户端。");
// 尝试在分区键 "key" 上获取锁
lockItem = client.tryAcquireLock(AcquireLockOptions.builder("key").build());
logger.info("尝试在 DynamoDB 上获取锁。");
if (lockItem.isPresent()) {
logger.info("已获取锁!如果我死了,我的锁将在 10 秒后过期。");
logger.info("否则,我将持有锁,直到停止心跳。");
isDynamoDBLockAccessed = true;
} else {
logger.info("无法获取锁!");
isDynamoDBLockAccessed = false;
}
client.close();
logger.info("结束:AWS DynamoDB lockDynamoDB");
return isDynamoDBLockAccessed;
}
@PreDestroy
public void destroy() {
logger.info("已触发 AWS DynamoDB 回调 - @PreDestroy。");
if (client != null && lockItem != null && lockItem.isPresent()) {
client.releaseLock(lockItem.get());
}
logger.info("已释放 AWS DynamoDB 锁。");
}
}
英文:
I am running same application with two different ports in my local. The code I have provided is only for testing. Here access_key and secret_key will be provided from environment variables in later stage.
When I run same application in different ports, I see both are able to acquire the lock in the dynamodb partition key.
This is totally new to me. Please need your support whether I need to make any locking mechanism in AWS DynamoDB from AWS Console.
Below are the AWS Console DynamoDB table snapshot and code snippet where I can see the log: "Acquired lock! If I die, my lock will expire in 10 seconds." is coming from both the running instance. As per my requirement, if I lock from one instance, the other instance should not acquire the lock where it should provide the log "Failed to acquire lock!".
> Also I am getting an error while executing the code in Spring Boot.
> AmazonDynamoDBLockClient : Heartbeat thread recieved interrupt, exiting run() (possibly exiting thread)
@Component
public class AwsDynamoDBConfiguration {
Logger logger = LoggerFactory.getLogger(AwsDynamoDBConfiguration.class);
/**
* AWS configuration.
*/
@Autowired
private AwsConfiguration awsConfiguration;
private static final AwsClientBuilder.EndpointConfiguration DYNAMODB_ENDPOINT = new AwsClientBuilder.EndpointConfiguration(
"https://dynamodb.us-east-1.amazonaws.com", "us-east-1");
private Optional<LockItem> lockItem;
private AmazonDynamoDBLockClient client;
public boolean lockDynamoDB() throws InterruptedException, IOException {
logger.info("Start : AWS DynamoDB lockDynamoDB");
boolean isDynamoDBLockAccessed = false;
final AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.standard()
.withEndpointConfiguration(DYNAMODB_ENDPOINT)
.withCredentials(new AWSStaticCredentialsProvider(
new BasicAWSCredentials("access_key", "secret_key")))
.build();
logger.info("DynamoDB created.");
// Whether or not to create a heartbeating background thread
final boolean createHeartbeatBackgroundThread = true;
// build the lock client
client = new AmazonDynamoDBLockClient(AmazonDynamoDBLockClientOptions.builder(dynamoDB, "tbl_test_lock")
.withTimeUnit(TimeUnit.SECONDS).withLeaseDuration(100L).withHeartbeatPeriod(3L)
.withCreateHeartbeatBackgroundThread(createHeartbeatBackgroundThread).build());
logger.info("DynamoDB Client created.");
// try to acquire a lock on the partition key "key"
lockItem = client.tryAcquireLock(AcquireLockOptions.builder("key").build());
logger.info("DynamoDB try acquire lock.");
if (lockItem.isPresent()) {
logger.info("Acquired lock! If I die, my lock will expire in 10 seconds.");
logger.info("Otherwise, I will hold it until I stop heartbeating.");
isDynamoDBLockAccessed = true;
} else {
logger.info("Failed to acquire lock!");
isDynamoDBLockAccessed = false;
}
client.close();
logger.info("End : AWS DynamoDB lockDynamoDB");
return isDynamoDBLockAccessed;
}
@PreDestroy
public void destroy() {
logger.info("AWS DynamoDB Callback triggered - @PreDestroy.");
if (client != null && lockItem != null && lockItem.isPresent()) {
client.releaseLock(lockItem.get());
}
logger.info("AWS DynamoDB Lock has been released.");
}
}
答案1
得分: 1
需要在条件下获取锁(client.getLock("key", Optional.empty())),并且它对我有效。
if (lockItem.isPresent()) {
client.getLock("key", Optional.empty());
logger.info("已获取锁!如果我死亡,我的锁将在 " + leaseDuration + " 秒后过期。");
logger.info("否则,我将一直持有它,直到我停止心跳。");
isDynamoDBLockAccessed = true;
} else {
logger.info("无法获取锁!");
isDynamoDBLockAccessed = false;
}
英文:
Need to get lock (client.getLock("key", Optional.empty())) under the condition and it worked for me.
if (lockItem.isPresent()) {
client.getLock("key", Optional.empty());
logger.info("Acquired lock! If I die, my lock will expire in " + leaseDuration + " seconds.");
logger.info("Otherwise, I will hold it until I stop heartbeating.");
isDynamoDBLockAccessed = true;
} else {
logger.info("Failed to acquire lock!");
isDynamoDBLockAccessed = false;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论