SQL Server nested transactions
Posted: Tue 07 Jul 2020 13:03
Hello,
Does SQL Server nested transactions supported in UniDAC ?
Does SQL Server nested transactions supported in UniDAC ?
Discussion forums for open issues and questions concerning database tools, data access components and developer tools from Devart
https://forums.devart.com/
Code: Select all
Conn.StartTransaction;
Conn.StartTransaction;
Conn.Commit;
Conn.Commit;
Code: Select all
DECLARE @cnt INT
BEGIN TRAN
SELECT @cnt = @@TRANCOUNT
PRINT '1: ' + CONVERT(VARCHAR, @cnt)
BEGIN TRAN
SELECT @cnt = @@TRANCOUNT
PRINT '2: ' + CONVERT(VARCHAR, @cnt)
COMMIT
SELECT @cnt = @@TRANCOUNT
PRINT '3: ' + CONVERT(VARCHAR, @cnt)
COMMIT
SELECT @cnt = @@TRANCOUNT
PRINT '4: ' + CONVERT(VARCHAR, @cnt)
Code: Select all
program nested_transaction_mock;
{$APPTYPE CONSOLE}
uses
Classes,
SysUtils,
Generics.Collections;
type
TUniConnectionMock = class(TComponent)
private
fTransansactionStack: TStack<string>;
function NewTransactionName: string;
function GetInTransaction: Boolean;
function GetTransactionDepth: Integer;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure StartTransaction; virtual;
procedure Commit; virtual;
procedure Rollback; virtual;
property InTransaction: Boolean read GetInTransaction;
property TransactionDepth: Integer read GetTransactionDepth;
end;
{ TUniConnectionMock }
constructor TUniConnectionMock.Create(AOwner: TComponent);
begin
inherited Create( AOwner );
fTransansactionStack := TStack<string>.Create;
end;
destructor TUniConnectionMock.Destroy;
begin
fTransansactionStack.Free;
inherited Destroy;
end;
function TUniConnectionMock.GetInTransaction: Boolean;
begin
Result := GetTransactionDepth > 0;
end;
function TUniConnectionMock.GetTransactionDepth: Integer;
begin
Result := fTransansactionStack.Count;
end;
function TUniConnectionMock.NewTransactionName: string;
var Guid: TGUID;
begin;
CreateGUID( Guid );
Result := GUIDToString( Guid );
Result := Copy(Result, 2, Length(Result) - 2);
end;
procedure TUniConnectionMock.StartTransaction;
var
lTransactionname: string;
begin
lTransactionname := NewTransactionName;
fTransansactionStack.Push( lTransactionname );
// place here native code for start SQL Server transaction with generated name
// BEGIN TRAN <lTransactionname>;
end;
procedure TUniConnectionMock.Commit;
var
lTransactionname: string;
begin
if InTransaction then begin
lTransactionname := fTransansactionStack.Extract;
// place here native code for commit SQL Server transaction with saved name
// COMMIT TRAN <lTransactionname>;
end;
end;
procedure TUniConnectionMock.Rollback;
begin
if InTransaction then begin
// place here native code for rollback all nested SQL Server transaction
// ROLLBACK TRAN
fTransansactionStack.Clear;
end;
end;
var
m: TUniConnectionMock;
procedure Print;
begin
Writeln('InTransaction: ', m.InTransaction, ', TransactionDepth: ', m.TransactionDepth);
end;
begin
m := TUniConnectionMock.Create( nil );
try
Print;
m.StartTransaction;
Print;
m.StartTransaction;
Print;
m.Commit;
Print;
m.Commit;
Print;
Writeln('-----------------');
m.StartTransaction;
Print;
m.StartTransaction;
Print;
m.Rollback;
Print;
finally
m.Free;
end;
end.