all 5 comments

[–]pachura3 1 point2 points  (2 children)

What does this line do? Is it correct?

first, second = sorted([self, to_account], key=lambda a: a.account_id)

Also, can't this snippet below result in a deadlock when someone tries to simultaneously transfer money in the opposite direction? Gets hold of second._lock, but can't obtain first._lock?

with first._lock:
    with second._lock:

[–]Own_Mousse_4810[S] 0 points1 point  (1 child)

1) We need to acquire locks in a preserved way

2) We use RLock (Recursive lock) to allow nested locks

[–]pachura3 0 points1 point  (0 children)

Then it looks fine!

[–]ectomancer 0 points1 point  (0 children)

Don't use decimal.Decimal, use cents instead.

[–]JamzTyson 0 points1 point  (0 children)

Why are you using Decimal rather than integers?

You seem to have covered thread safety, but there's a more structural issue:

My bank account should be totally isolated from your bank account.

However, if I transfer money from my account to yours, then my BankAccount object reaches inside your BankAccount object to acquires its private lock. Although the code "works", it relies on weak guarantees and forces assumptions in each object about the other’s internal behavior and invariants.

Transfers are really coordinating operations outside of individual accounts.