Skip to content

Commit 99ecc03

Browse files
committed
select for update is one approach [with_for_update]
1 parent d251899 commit 99ecc03

2 files changed

Lines changed: 21 additions & 12 deletions

File tree

‎src/allocation/repository.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ def add(self, product):
2222
self.session.add(product)
2323

2424
def get(self, sku):
25-
print(sku, type(sku))
26-
return self.session.query(model.Product).filter_by(sku=sku).first()
25+
return self.session.query(model.Product) \
26+
.filter_by(sku=sku) \
27+
.with_for_update() \
28+
.first()
2729

‎tests/integration/test_uow.py‎

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ class MyException(Exception):
7575
import traceback
7676
import time
7777

78-
def try_to_allocate(sku, session_factory, exceptions):
79-
line = model.OrderLine(random_ref('o'), sku, 10)
78+
def try_to_allocate(orderid, sku, session_factory, exceptions):
79+
line = model.OrderLine(orderid, sku, 10)
8080
try:
8181
with unit_of_work.start(session_factory) as uow:
8282
product = uow.products.get(sku=sku)
@@ -88,16 +88,18 @@ def try_to_allocate(sku, session_factory, exceptions):
8888
exceptions.append(e)
8989

9090

91-
def test_concurrent_sessions_cannot_both_increment_product_version(postgres_session_factory):
91+
def test_integrity_of_concurrent_updates_to_product_version(postgres_session_factory):
9292
sku, batch = random_ref('s'), random_ref('b')
9393
session = postgres_session_factory()
9494
insert_batch(session, batch, sku, 100, eta=None, product_version=3)
9595
session.commit()
9696

9797
exceptions = []
98-
target = lambda: try_to_allocate(sku, postgres_session_factory, exceptions)
99-
t1 = threading.Thread(target=target)
100-
t2 = threading.Thread(target=target)
98+
o1, o2 = random_ref('o1'), random_ref('o2')
99+
target1 = lambda: try_to_allocate(o1, sku, postgres_session_factory, exceptions)
100+
target2 = lambda: try_to_allocate(o2, sku, postgres_session_factory, exceptions)
101+
t1 = threading.Thread(target=target1)
102+
t2 = threading.Thread(target=target2)
101103
t1.start()
102104
t2.start()
103105
t1.join()
@@ -107,10 +109,15 @@ def test_concurrent_sessions_cannot_both_increment_product_version(postgres_sess
107109
"SELECT version_number FROM products WHERE sku=:sku",
108110
dict(sku=sku),
109111
)
112+
assert version == 5
110113
assert exceptions == []
111-
assert version == 4
112-
assert list(session.execute(
113-
"SELECT * FROM allocations JOIN batches ON allocations.batch_id = batches.id WHERE sku=:sku",
114+
orders = list(session.execute(
115+
"SELECT orderid FROM allocations"
116+
" JOIN batches ON allocations.batch_id = batches.id"
117+
" JOIN order_lines ON allocations.orderline_id = order_lines.id"
118+
" WHERE order_lines.sku=:sku",
114119
dict(sku=sku),
115-
)) == []
120+
))
121+
orders = set([orders[0][0], orders[1][0]])
122+
assert orders == {o1, o2}
116123

0 commit comments

Comments
 (0)