The Salesforce docs say that
The lock gets released when the transaction completes
Does that mean when the record is updated, or when the execution context completes?
The lock is released end the transaction. The boundary you cross to do so may be a method exit, trigger completion, etc. It may be when you exit the static context entirely, but it will not be released simply by performing
DML Statement is only a part of the transaction, and will not constitute a transaction boundary in itself.
Here is how the
Apex Developer Guide explains transactions:
An Apex transaction represents a set of operations that are executed as a single unit. All DML operations in a transaction either complete successfully, or if an error occurs in one operation, the entire transaction is rolled back and no data is committed to the database. The boundary of a transaction can be a trigger, a class method, an anonymous block of code, a Visualforce page, or a custom Web service method.
All operations that occur inside the transaction boundary represent a single unit of operations. This also applies for calls that are made from the transaction boundary to external code, such as classes or triggers that get fired as a result of the code running in the transaction boundary. For example, consider the following chain of operations: a custom Apex Web service method causes a trigger to fire, which in turn calls a method in a class. In this case, all changes are committed to the database only after all operations in the transaction finish executing and don’t cause any errors. If an error occurs in any of the intermediate steps, all database changes are rolled back and the transaction isn’t committed.
As far as I understand it, you can have child transactions that have their own boundaries (but not static governors). It’s kind of like a transaction stack.
For instance, if you update a record, any triggers it fires will cross a transaction boundary and create a child transaction. Because you have not yet exited the parent transaction, any locks placed there should still hold. Eventually, the triggers will finish executing, and you will return to the parent transaction. Lock still holds. Only once you cross a transaction boundary that exits the transaction which placed the lock will it be released.
In the below sample timeline, the lock won’t be released until
METHOD_ENTRY lock update triggers complete METHOD_EXIT |------------|---------|-------------------|------------------------------------| Child Transaction