or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddistributed-locking.mdfactory-utilities.mdindex.mdservice-discovery.md

distributed-locking.mddocs/

0

# Distributed Locking

1

2

Distributed locking capabilities for coordination and synchronization across microservices. Supports lock expiration, try-lock operations, and remote lock management with automatic cleanup.

3

4

## Capabilities

5

6

### Basic Lock Operations

7

8

Core distributed locking operations for synchronization across microservices.

9

10

```java { .api }

11

public interface LockService {

12

// Acquire distributed lock (blocking)

13

Boolean lock(LockInstance instance) throws NacosException;

14

15

// Release distributed lock

16

Boolean unLock(LockInstance instance) throws NacosException;

17

18

// Try to acquire lock without blocking (non-blocking)

19

Boolean remoteTryLock(LockInstance instance) throws NacosException;

20

21

// Release lock remotely

22

Boolean remoteReleaseLock(LockInstance instance) throws NacosException;

23

24

// Shutdown the lock service

25

void shutdown() throws NacosException;

26

}

27

```

28

29

#### Usage Examples

30

31

```java

32

import com.alibaba.nacos.api.lock.LockService;

33

import com.alibaba.nacos.api.lock.NacosLockFactory;

34

import com.alibaba.nacos.api.lock.model.LockInstance;

35

import com.alibaba.nacos.api.exception.NacosException;

36

37

// Create lock service

38

Properties props = new Properties();

39

props.setProperty("serverAddr", "localhost:8848");

40

LockService lockService = NacosLockFactory.createLockService(props);

41

42

// Create lock instance

43

LockInstance lockInstance = new LockInstance();

44

lockInstance.setKey("order-processing-lock");

45

lockInstance.setExpiredTime(30000L); // 30 seconds in milliseconds

46

47

try {

48

// Acquire lock

49

Boolean acquired = lockService.lock(lockInstance);

50

51

if (acquired) {

52

System.out.println("Lock acquired successfully");

53

54

// Perform critical section operations

55

processOrder();

56

57

} else {

58

System.out.println("Failed to acquire lock");

59

}

60

61

} finally {

62

// Always release lock in finally block

63

lockService.unLock(lockInstance);

64

}

65

```

66

67

### Non-blocking Lock Operations

68

69

Try-lock operations that don't block if the lock is unavailable.

70

71

```java

72

// Non-blocking lock attempt

73

LockInstance lockInstance = new LockInstance();

74

lockInstance.setKey("cache-update-lock");

75

lockInstance.setExpiredTime(60000L); // 60 seconds in milliseconds

76

77

// Try to acquire lock without blocking

78

Boolean acquired = lockService.remoteTryLock(lockInstance);

79

80

if (acquired) {

81

try {

82

// Perform cache update

83

updateCache();

84

85

} finally {

86

// Release lock

87

lockService.remoteReleaseLock(lockInstance);

88

}

89

} else {

90

System.out.println("Another process is updating cache, skipping...");

91

}

92

```

93

94

### Lock with Automatic Expiration

95

96

Locks with built-in expiration to prevent deadlocks from process failures.

97

98

```java

99

// Lock with automatic expiration (prevents deadlocks)

100

String lockKey = "database-migration-lock";

101

String lockValue = "migration-" + UUID.randomUUID().toString();

102

103

// Lock expires after 300 seconds (5 minutes)

104

boolean acquired = lockService.lock(lockKey, lockValue, 300);

105

106

if (acquired) {

107

try {

108

// Perform long-running database migration

109

runDatabaseMigration();

110

111

} catch (Exception e) {

112

System.err.println("Migration failed: " + e.getMessage());

113

// Lock will automatically expire if process crashes

114

115

} finally {

116

// Explicitly release lock when done

117

lockService.unLock(lockKey, lockValue);

118

}

119

}

120

```

121

122

### Distributed Coordination Patterns

123

124

Common patterns for distributed coordination using locks.

125

126

#### Mutual Exclusion Pattern

127

128

```java

129

public class OrderProcessor {

130

private final LockService lockService;

131

private final String instanceId;

132

133

public OrderProcessor(LockService lockService) {

134

this.lockService = lockService;

135

this.instanceId = "processor-" + InetAddress.getLocalHost().getHostName();

136

}

137

138

public void processOrderBatch(List<Order> orders) throws NacosException {

139

String lockKey = "order-batch-processing";

140

141

// Ensure only one instance processes orders at a time

142

boolean acquired = lockService.lock(lockKey, instanceId, 120); // 2 minutes

143

144

if (acquired) {

145

try {

146

System.out.println("Processing " + orders.size() + " orders...");

147

148

for (Order order : orders) {

149

processOrder(order);

150

}

151

152

System.out.println("Batch processing completed");

153

154

} finally {

155

lockService.unLock(lockKey, instanceId);

156

}

157

} else {

158

System.out.println("Another instance is processing orders");

159

}

160

}

161

}

162

```

163

164

#### Leader Election Pattern

165

166

```java

167

public class LeaderElection {

168

private final LockService lockService;

169

private final String nodeId;

170

private volatile boolean isLeader = false;

171

172

public LeaderElection(LockService lockService, String nodeId) {

173

this.lockService = lockService;

174

this.nodeId = nodeId;

175

}

176

177

public void tryBecomeLeader() {

178

String leaderLock = "cluster-leader-election";

179

180

try {

181

// Try to become leader (non-blocking)

182

boolean becameLeader = lockService.remoteTryLock(leaderLock, nodeId, 60);

183

184

if (becameLeader && !isLeader) {

185

isLeader = true;

186

System.out.println("Node " + nodeId + " became leader");

187

startLeaderTasks();

188

189

} else if (!becameLeader && isLeader) {

190

isLeader = false;

191

System.out.println("Node " + nodeId + " lost leadership");

192

stopLeaderTasks();

193

}

194

195

} catch (NacosException e) {

196

System.err.println("Leader election failed: " + e.getMessage());

197

}

198

}

199

200

public void resignLeadership() {

201

if (isLeader) {

202

try {

203

lockService.remoteReleaseLock("cluster-leader-election", nodeId);

204

isLeader = false;

205

stopLeaderTasks();

206

207

} catch (NacosException e) {

208

System.err.println("Failed to resign leadership: " + e.getMessage());

209

}

210

}

211

}

212

}

213

```

214

215

#### Resource Pool Management

216

217

```java

218

public class ResourcePoolManager {

219

private final LockService lockService;

220

private final String poolName;

221

222

public ResourcePoolManager(LockService lockService, String poolName) {

223

this.lockService = lockService;

224

this.poolName = poolName;

225

}

226

227

public Resource acquireResource(String resourceId) throws NacosException {

228

String lockKey = poolName + "-resource-" + resourceId;

229

String lockValue = "consumer-" + Thread.currentThread().getId();

230

231

// Try to acquire resource for 30 seconds

232

boolean acquired = lockService.remoteTryLock(lockKey, lockValue, 30);

233

234

if (acquired) {

235

return new Resource(resourceId, () -> {

236

try {

237

lockService.remoteReleaseLock(lockKey, lockValue);

238

} catch (NacosException e) {

239

System.err.println("Failed to release resource: " + e.getMessage());

240

}

241

});

242

} else {

243

throw new ResourceUnavailableException("Resource " + resourceId + " is in use");

244

}

245

}

246

}

247

```

248

249

## Types

250

251

### Lock Instance Model

252

253

```java { .api }

254

public class LockInstance implements Serializable {

255

private String key;

256

private Long expiredTime;

257

private Map<String, ? extends Serializable> params;

258

private String lockType;

259

260

// Constructors

261

public LockInstance();

262

public LockInstance(String key, Long expiredTime, String lockType);

263

264

// Lock identification

265

public String getKey();

266

public void setKey(String key);

267

268

public String getLockType();

269

public void setLockType(String lockType);

270

271

// Expiration management

272

public Long getExpiredTime();

273

public void setExpiredTime(Long expiredTime);

274

275

// Additional parameters

276

public Map<String, ? extends Serializable> getParams();

277

public void setParams(Map<String, ? extends Serializable> params);

278

279

// Utility methods

280

public Boolean lock(LockService lockService) throws NacosException;

281

public Boolean unLock(LockService lockService) throws NacosException;

282

}

283

```

284

285

### Lock Operation Types

286

287

```java { .api }

288

public enum LockOperationEnum {

289

LOCK("lock"),

290

UNLOCK("unlock"),

291

TRY_LOCK("tryLock"),

292

RELEASE_LOCK("releaseLock");

293

294

private final String operation;

295

296

LockOperationEnum(String operation) {

297

this.operation = operation;

298

}

299

300

public String getOperation();

301

}

302

```

303

304

### Lock Configuration

305

306

```java { .api }

307

// Lock-specific property keys

308

public class LockPropertyKeyConst {

309

// Connection settings

310

public static final String LOCK_SERVER_ADDR = "lockServerAddr";

311

public static final String LOCK_NAMESPACE = "lockNamespace";

312

313

// Timeout settings

314

public static final String LOCK_TIMEOUT = "lockTimeout";

315

public static final String LOCK_RETRY_INTERVAL = "lockRetryInterval";

316

public static final String LOCK_MAX_RETRY = "lockMaxRetry";

317

318

// Default expiration

319

public static final String DEFAULT_LOCK_EXPIRATION = "defaultLockExpiration";

320

321

// Performance tuning

322

public static final String LOCK_THREAD_POOL_SIZE = "lockThreadPoolSize";

323

public static final String LOCK_HEARTBEAT_INTERVAL = "lockHeartbeatInterval";

324

}

325

```

326

327

### Lock Exceptions

328

329

```java { .api }

330

// Lock-specific exceptions

331

public class LockException extends NacosException {

332

public static final int LOCK_ALREADY_HELD = 10001;

333

public static final int LOCK_NOT_FOUND = 10002;

334

public static final int LOCK_EXPIRED = 10003;

335

public static final int LOCK_INVALID_OWNER = 10004;

336

337

public LockException(int errCode, String errMsg);

338

public LockException(int errCode, String errMsg, Throwable cause);

339

}

340

```

341

342

## Best Practices

343

344

### Lock Key Naming

345

346

Use descriptive, hierarchical lock keys to avoid conflicts:

347

348

```java

349

// Good: descriptive hierarchy

350

"order-processing-batch-daily"

351

"cache-update-user-profiles"

352

"database-migration-v2.1"

353

"leader-election-notification-service"

354

355

// Bad: generic names

356

"lock1"

357

"process"

358

"update"

359

```

360

361

### Lock Value Generation

362

363

Use unique, identifiable lock values:

364

365

```java

366

// Include instance/thread identification

367

String lockValue = instanceId + "-" + Thread.currentThread().getId() + "-" + System.currentTimeMillis();

368

369

// Or use UUID for uniqueness

370

String lockValue = UUID.randomUUID().toString();

371

```

372

373

### Expiration Time Guidelines

374

375

Set appropriate expiration times based on operation duration:

376

377

```java

378

// Short operations (few seconds)

379

lockService.lock(lockKey, lockValue, 30);

380

381

// Medium operations (minutes)

382

lockService.lock(lockKey, lockValue, 300);

383

384

// Long operations (hours) - consider breaking into smaller chunks

385

lockService.lock(lockKey, lockValue, 3600);

386

```

387

388

### Error Handling

389

390

Always handle lock failures gracefully:

391

392

```java

393

try {

394

boolean acquired = lockService.lock(lockKey, lockValue, 60);

395

396

if (!acquired) {

397

// Handle inability to acquire lock

398

scheduleRetry();

399

return;

400

}

401

402

// Perform critical section

403

performCriticalOperation();

404

405

} catch (NacosException e) {

406

// Handle network or server errors

407

handleLockError(e);

408

409

} finally {

410

// Always attempt to release lock

411

try {

412

lockService.unLock(lockKey, lockValue);

413

} catch (NacosException e) {

414

// Log but don't fail - lock will expire

415

logger.warn("Failed to release lock: " + e.getMessage());

416

}

417

}

418

```