{"id":6205,"library":"python-dynamodb-lock","title":"Python DynamoDB Lock","description":"Python DynamoDB Lock is a general-purpose distributed locking library built on top of DynamoDB. It supports both coarse-grained and fine-grained locking, heavily inspired by the Java-based AmazonDynamoDBLockClient. The current version is 0.9.1, with the last release in October 2018. While functional, its development appears to be in maintenance mode.","status":"maintenance","version":"0.9.1","language":"en","source_language":"en","source_url":"https://github.com/mohankishore/python_dynamodb_lock","tags":["AWS","DynamoDB","distributed-lock","locking","concurrency"],"install":[{"cmd":"pip install python-dynamodb-lock","lang":"bash","label":"Install stable release"}],"dependencies":[{"reason":"Required for interacting with AWS DynamoDB.","package":"boto3","optional":false}],"imports":[{"symbol":"DynamoDBLockClient","correct":"from python_dynamodb_lock import DynamoDBLockClient"}],"quickstart":{"code":"import boto3\nfrom python_dynamodb_lock import DynamoDBLockClient\nimport os\nimport time\n\n# Configure AWS credentials and region (e.g., via environment variables or ~/.aws/credentials)\n# For local testing, you might use 'local' endpoint_url\ndynamodb_resource = boto3.resource(\n    'dynamodb',\n    region_name=os.environ.get('AWS_REGION', 'us-east-1'),\n    endpoint_url=os.environ.get('DYNAMODB_ENDPOINT_URL', None)\n)\n\ntable_name = os.environ.get('DYNAMODB_LOCK_TABLE_NAME', 'MyDistributedLockTable')\n\n# It's recommended to create the table beforehand with a 'lock_key' primary key and TTL enabled\n# For demonstration, we'll try to create it if it doesn't exist\ntry:\n    table = dynamodb_resource.Table(table_name)\n    table.load()\nexcept dynamodb_resource.meta.client.exceptions.ResourceNotFoundException:\n    print(f\"Creating DynamoDB table: {table_name}\")\n    dynamodb_resource.create_table(\n        TableName=table_name,\n        KeySchema=[{'AttributeName': 'lock_key', 'KeyType': 'HASH'}],\n        AttributeDefinitions=[{'AttributeName': 'lock_key', 'AttributeType': 'S'}],\n        BillingMode='PAY_PER_REQUEST'\n    )\n    # Wait for the table to be active\n    dynamodb_resource.meta.client.get_waiter('table_exists').wait(TableName=table_name)\n    print(f\"Table {table_name} created.\")\n\n# Instantiate the lock client\n# The 'owner_name' helps identify who holds the lock (e.g., hostname + process ID)\nlock_client = DynamoDBLockClient(\n    dynamodb_resource,\n    table_name=table_name,\n    owner_name=f\"{os.uname()[1]}-{os.getpid()}\"\n)\n\nlock_key = \"my-critical-resource\"\n\ntry:\n    print(f\"Attempting to acquire lock for {lock_key}...\")\n    # Use the 'lock' method as a context manager for a specific lock\n    with lock_client.lock(lock_key):\n        print(f\"Successfully acquired lock for {lock_key}. Performing critical section...\")\n        # Simulate work\n        time.sleep(5)\n        print(f\"Finished critical section for {lock_key}.\")\n    print(f\"Lock for {lock_key} automatically released.\")\nexcept Exception as e:\n    print(f\"Failed to acquire or process with lock for {lock_key}: {e}\")\nfinally:\n    # It's important to close the client to stop background heartbeat threads\n    print(\"Closing lock client...\")\n    lock_client.close() \n    print(\"Lock client closed.\")","lang":"python","description":"This quickstart demonstrates how to acquire and release a distributed lock using `DynamoDBLockClient` as a context manager for a specific resource. It includes basic setup for a DynamoDB table and shows how to handle the critical section."},"warnings":[{"fix":"Evaluate against modern alternatives or consider contributing to the project if extended functionality or maintenance is required.","message":"The library's last release was in October 2018. While functional, it may not receive active updates or support for newer Python versions/AWS features.","severity":"breaking","affected_versions":"<=0.9.1"},{"fix":"Design your application with eventual consistency in mind or implement application-level checks to handle potential conflicts if a lock is stolen. Do not assume transactional guarantees across lock acquisition and business logic.","message":"This library does NOT participate in distributed transactions. If an application holding a lock experiences prolonged delays (e.g., GC pauses, errors) preventing heartbeats, another client might assume the lock is abandoned and acquire it. The original client might then commit changes even after its lock has been 'stolen', leading to data inconsistencies.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure your DynamoDB table has a TTL attribute configured (default: 'expiry_time') and that `expiry_period` is set appropriately during client instantiation to allow timely cleanup of abandoned locks. Implement robust error handling and graceful shutdown procedures where possible.","message":"Sudden process termination of a client will leave its acquired locks in DynamoDB until they eventually expire based on their Time-To-Live (TTL) attribute. This expiry is not immediate and can take up to 24 hours.","severity":"gotcha","affected_versions":"All"},{"fix":"Explicitly manage lock release for individual `DynamoDBLock` instances. If you need to force release all locks on shutdown, you might need to iterate through and release them, or rely on TTL for cleanup (see previous warning).","message":"Calling `lock_client.close()` by default does NOT release all locks owned by that client. This design prevents premature lock release while application logic might still be processing under the assumption of holding the lock.","severity":"gotcha","affected_versions":"All"},{"fix":"Before using the library, ensure your DynamoDB table adheres to the required schema and has TTL enabled. Example table creation is provided in the quickstart.","message":"The DynamoDB table used for locking must be configured with a primary key (default: 'lock_key' of type String) and it is highly recommended to enable and configure a TTL attribute (default: 'expiry_time') to allow DynamoDB to automatically clean up old/abandoned lock entries.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}