Skip to content

Commit 2e1c605

Browse files
committed
review: conditionally skip nested transaction in DML refresh when flag is on; add snapshot functional test
1 parent 5e9b033 commit 2e1c605

2 files changed

Lines changed: 51 additions & 5 deletions

File tree

dbt/include/sqlserver/macros/materializations/models/table/table_dml_refresh.sql

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,18 @@
5555

5656
{# Atomic DML swap — RCSI protects concurrent readers #}
5757
{# When dbt_sqlserver_use_dbt_transactions is off (default), autocommit #}
58-
{# ensures only this explicit transaction exists. When the flag is on, #}
59-
{# the statement call auto-begins an outer transaction first. SQL Server #}
60-
{# increments @@TRANCOUNT for nested BEGIN TRANSACTION statements. #}
61-
{# Inner COMMIT only decrements @@TRANCOUNT; durability occurs when the outermost #}
62-
{# transaction commits. A ROLLBACK rolls back the full transaction. #}
58+
{# means we need the explicit BEGIN/COMMIT. When the flag is on, dbt #}
59+
{# already wraps the statement call in a transaction, so skip it. #}
6360
{% call statement('dml_refresh_swap') -%}
61+
{% if not adapter.behavior.dbt_sqlserver_use_dbt_transactions %}
6462
BEGIN TRANSACTION;
63+
{% endif %}
6564
DELETE FROM {{ target_relation }};
6665
INSERT INTO {{ target_relation }} ({{ column_list }})
6766
SELECT {{ column_list }} FROM {{ refresh_relation }};
67+
{% if not adapter.behavior.dbt_sqlserver_use_dbt_transactions %}
6868
COMMIT TRANSACTION;
69+
{% endif %}
6970
{%- endcall %}
7071

7172
{# Cleanup scratch table #}

tests/functional/adapter/dbt/test_transactions.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,48 @@ def test_failed_then_successful_run(self, project):
174174
rows = project.run_sql("select id from {schema}.good_model", fetch="all")
175175
assert len(rows) == 1
176176
assert rows[0][0] == 1
177+
178+
179+
_snapshot_seed_csv = """id,name,updated_at
180+
1,alice,2024-01-01 00:00:00
181+
2,bob,2024-01-01 00:00:00
182+
"""
183+
184+
_snapshot_sql = """
185+
{% snapshot snap %}
186+
{{ config(
187+
target_schema=schema,
188+
unique_key='id',
189+
strategy='timestamp',
190+
updated_at='updated_at',
191+
) }}
192+
select * from {{ ref('snap_seed') }}
193+
{% endsnapshot %}
194+
"""
195+
196+
197+
class TestSnapshotTransactionsOn(BaseTransactionsEnabled):
198+
@pytest.fixture(scope="class")
199+
def seeds(self):
200+
return {"snap_seed.csv": _snapshot_seed_csv}
201+
202+
@pytest.fixture(scope="class")
203+
def snapshots(self):
204+
return {"snap.sql": _snapshot_sql}
205+
206+
@pytest.fixture(scope="class")
207+
def models(self):
208+
return {}
209+
210+
def test_snapshot_create_and_merge(self, project):
211+
run_dbt(["seed"])
212+
results = run_dbt(["snapshot"])
213+
assert len(results) == 1
214+
assert results[0].status == "success"
215+
216+
rows = project.run_sql("select count(*) from {schema}.snap", fetch="one")
217+
assert rows[0] == 2
218+
219+
results = run_dbt(["snapshot"])
220+
assert len(results) == 1
221+
assert results[0].status == "success"

0 commit comments

Comments
 (0)