mirror of
https://gitea.invidious.io/iv-org/shard-crystal-db.git
synced 2024-08-15 00:53:32 +00:00
Close a transaction when return
ing from within its block (#167)
This commit is contained in:
parent
167b55966e
commit
e076a08cd0
2 changed files with 31 additions and 10 deletions
|
@ -95,6 +95,20 @@ describe DB::Transaction do
|
||||||
t.committed.should be_false
|
t.committed.should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "transaction with block from connection should be committed if `return` is called" do
|
||||||
|
t = uninitialized DummyDriver::DummyTransaction
|
||||||
|
|
||||||
|
with_witness do |w|
|
||||||
|
with_dummy_connection do |cnn|
|
||||||
|
t = return_from_txn(cnn).as(DummyDriver::DummyTransaction)
|
||||||
|
w.check
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
t.rolledback.should be_false
|
||||||
|
t.committed.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
it "transaction can be committed within block" do
|
it "transaction can be committed within block" do
|
||||||
with_dummy_connection do |cnn|
|
with_dummy_connection do |cnn|
|
||||||
cnn.transaction do |tx|
|
cnn.transaction do |tx|
|
||||||
|
@ -211,3 +225,9 @@ describe DB::Transaction do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private def return_from_txn(cnn)
|
||||||
|
cnn.transaction do |tx|
|
||||||
|
return tx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -13,25 +13,26 @@ module DB
|
||||||
# can be called explicitly.
|
# can be called explicitly.
|
||||||
# Returns the value of the block.
|
# Returns the value of the block.
|
||||||
def transaction(& : Transaction -> T) : T? forall T
|
def transaction(& : Transaction -> T) : T? forall T
|
||||||
|
rollback = false
|
||||||
# TODO: Cast to workaround crystal-lang/crystal#9483
|
# TODO: Cast to workaround crystal-lang/crystal#9483
|
||||||
# begin_transaction returns a Tx where Tx < Transaction
|
# begin_transaction returns a Tx where Tx < Transaction
|
||||||
tx = begin_transaction.as(Transaction)
|
tx = begin_transaction.as(Transaction)
|
||||||
begin
|
begin
|
||||||
res = yield tx
|
res = yield tx
|
||||||
rescue DB::Rollback
|
rescue DB::Rollback
|
||||||
tx.rollback unless tx.closed?
|
rollback = true
|
||||||
res
|
res
|
||||||
rescue e
|
rescue e
|
||||||
unless tx.closed?
|
rollback = true
|
||||||
# Ignore error in rollback.
|
|
||||||
# It would only be a secondary error to the original one, caused by
|
|
||||||
# corrupted connection state.
|
|
||||||
tx.rollback rescue nil
|
|
||||||
end
|
|
||||||
raise e
|
raise e
|
||||||
else
|
ensure
|
||||||
tx.commit unless tx.closed?
|
unless tx.closed?
|
||||||
res
|
if rollback
|
||||||
|
tx.rollback
|
||||||
|
else
|
||||||
|
tx.commit
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue