基于数据库的分布式锁 java代码
时间: 2023-07-25 07:06:43 浏览: 56
以下是基于数据库的分布式锁的Java代码示例:
```java
public class DistributedLock {
private static final String LOCK_NAME_PREFIX = "distributed_lock_";
private final DataSource dataSource;
private final String lockName;
public DistributedLock(DataSource dataSource, String lockName) {
this.dataSource = dataSource;
this.lockName = LOCK_NAME_PREFIX + lockName;
}
public boolean acquire() {
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
// Insert a new row with the lock name
try (PreparedStatement statement = connection.prepareStatement(
"INSERT INTO locks (name) VALUES (?) ON CONFLICT DO NOTHING")) {
statement.setString(1, lockName);
statement.executeUpdate();
}
// Try to acquire the lock by updating the row with a unique value
try (PreparedStatement statement = connection.prepareStatement(
"UPDATE locks SET acquired_by = ? WHERE name = ? AND acquired_by IS NULL")) {
statement.setString(1, UUID.randomUUID().toString());
statement.setString(2, lockName);
int rowsUpdated = statement.executeUpdate();
if (rowsUpdated == 1) {
connection.commit();
return true;
}
}
connection.rollback();
return false;
} catch (SQLException e) {
throw new RuntimeException("Unable to acquire lock", e);
}
}
public void release() {
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(
"UPDATE locks SET acquired_by = NULL WHERE name = ?")) {
statement.setString(1, lockName);
statement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Unable to release lock", e);
}
}
}
```
在此示例中,我们使用了一个名为“locks”的数据库表来存储锁的信息。该表包含一个“name”列和一个“acquired_by”列。当我们尝试获取锁时,我们首先插入一个新行,然后尝试通过更新该行来获取锁。如果更新成功,则表示我们已经获得了锁,并且可以提交事务。如果更新失败,则表示其他进程已经获得了锁,并且必须回滚事务。释放锁时,我们只需要更新“acquired_by”列为NULL即可。
请注意,此代码示例仅用于演示目的。在实际生产环境中,您需要考虑更多方面,例如锁超时、死锁检测等。