mirror of
https://gitea.invidious.io/iv-org/shard-crystal-db.git
synced 2024-08-15 00:53:32 +00:00
add nested transaction with savepoints
This commit is contained in:
parent
9bde76865e
commit
c491bd8962
4 changed files with 243 additions and 3 deletions
|
@ -68,6 +68,29 @@ class DummyDriver < DB::Driver
|
|||
super
|
||||
@rolledback = true
|
||||
end
|
||||
|
||||
protected def create_save_point_transaction(parent, savepoint_name : String)
|
||||
DummySavePointTransaction.new(parent, savepoint_name)
|
||||
end
|
||||
end
|
||||
|
||||
class DummySavePointTransaction < DB::SavePointTransaction
|
||||
getter committed = false
|
||||
getter rolledback = false
|
||||
|
||||
def initialize(parent, savepoint_name)
|
||||
super(parent, savepoint_name)
|
||||
end
|
||||
|
||||
def commit
|
||||
super
|
||||
@committed = true
|
||||
end
|
||||
|
||||
def rollback
|
||||
super
|
||||
@rolledback = true
|
||||
end
|
||||
end
|
||||
|
||||
class DummyStatement < DB::Statement
|
||||
|
|
127
spec/save_point_transaction_spec.cr
Normal file
127
spec/save_point_transaction_spec.cr
Normal file
|
@ -0,0 +1,127 @@
|
|||
require "./spec_helper"
|
||||
|
||||
private class FooException < Exception
|
||||
end
|
||||
|
||||
private def with_dummy_top_transaction
|
||||
with_dummy_connection do |cnn|
|
||||
cnn.transaction do |tx|
|
||||
yield tx.as(DummyDriver::DummyTransaction), cnn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private def with_dummy_nested_transaction
|
||||
with_dummy_connection do |cnn|
|
||||
cnn.transaction do |tx|
|
||||
tx.transaction do |nested|
|
||||
yield nested.as(DummyDriver::DummySavePointTransaction), cnn
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe DB::SavePointTransaction do
|
||||
{% for context in [:with_dummy_top_transaction, :with_dummy_nested_transaction] %}
|
||||
describe "{{context.id}}" do
|
||||
it "begin/commit transaction from parent transaction" do
|
||||
{{context.id}} do |parent_tx|
|
||||
tx = parent_tx.begin_transaction
|
||||
tx.commit
|
||||
end
|
||||
end
|
||||
|
||||
it "begin/rollback transaction from parent transaction" do
|
||||
{{context.id}} do |parent_tx|
|
||||
tx = parent_tx.begin_transaction
|
||||
tx.rollback
|
||||
end
|
||||
end
|
||||
|
||||
it "raise if begin over existing transaction" do
|
||||
{{context.id}} do |parent_tx|
|
||||
parent_tx.begin_transaction
|
||||
expect_raises(DB::Error, "There is an existing nested transaction in this transaction") do
|
||||
parent_tx.begin_transaction
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "allow sequential transactions" do
|
||||
{{context.id}} do |parent_tx|
|
||||
tx = parent_tx.begin_transaction
|
||||
tx.rollback
|
||||
|
||||
tx = parent_tx.begin_transaction
|
||||
tx.commit
|
||||
end
|
||||
end
|
||||
|
||||
it "transaction with block from parent transaction should be committed" do
|
||||
t = uninitialized DummyDriver::DummySavePointTransaction
|
||||
|
||||
with_witness do |w|
|
||||
{{context.id}} do |parent_tx|
|
||||
parent_tx.transaction do |tx|
|
||||
if tx.is_a?(DummyDriver::DummySavePointTransaction)
|
||||
t = tx
|
||||
w.check
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
t.committed.should be_true
|
||||
t.rolledback.should be_false
|
||||
end
|
||||
end
|
||||
{% end %}
|
||||
|
||||
it "only nested transaction with block from parent transaction should be rolledback if raise DB::Rollback" do
|
||||
top = uninitialized DummyDriver::DummyTransaction
|
||||
t = uninitialized DummyDriver::DummySavePointTransaction
|
||||
|
||||
with_witness do |w|
|
||||
with_dummy_top_transaction do |parent_tx|
|
||||
top = parent_tx
|
||||
parent_tx.transaction do |tx|
|
||||
if tx.is_a?(DummyDriver::DummySavePointTransaction)
|
||||
t = tx
|
||||
w.check
|
||||
end
|
||||
raise DB::Rollback.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
t.rolledback.should be_true
|
||||
t.committed.should be_false
|
||||
|
||||
top.rolledback.should be_false
|
||||
top.committed.should be_true
|
||||
end
|
||||
|
||||
it "only nested transaction with block from parent nested transaction should be rolledback if raise DB::Rollback" do
|
||||
top = uninitialized DummyDriver::DummySavePointTransaction
|
||||
t = uninitialized DummyDriver::DummySavePointTransaction
|
||||
|
||||
with_witness do |w|
|
||||
with_dummy_nested_transaction do |parent_tx|
|
||||
top = parent_tx
|
||||
parent_tx.transaction do |tx|
|
||||
if tx.is_a?(DummyDriver::DummySavePointTransaction)
|
||||
t = tx
|
||||
w.check
|
||||
end
|
||||
raise DB::Rollback.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
t.rolledback.should be_true
|
||||
t.committed.should be_false
|
||||
|
||||
top.rolledback.should be_false
|
||||
top.committed.should be_true
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue