Why is column value going negative even with checks
The error cause is a race condition that is happening, because your query was not immune to it.
There are ways to code your queries to avoid it (atomic update, transactions, etc.).
Because you did not use table locking or transactions, you ended up with an error when your query read an updated value from another thread. This produced a negative value.  

Proposed solution:  

Issue both SELECT and UPDATE in a single statement to avoid race condition, as you have tried, however, select from underlying table into a session variable.
That way, you can have control of the time when you select a value, and not get value from another thread.  

I have rewritten your code to use user-defined, session variables.  

Update 1 rewritten:  

-- @blnc and @lckd are user-defined variables  
UPDATE tablename  
SET locked = (@lckd + x)  
WHERE id = 1  
    AND ((@blnc := balance) - (@lckd := locked)) &gt;= x;


Update 2 rewritten:

-- @blnc and @lckd are user-defined variables  
UPDATE tablename  
SET balance = (@blnc := balance) - x  
    , locked = (@lckd := locked) - x  
WHERE id = 1;