Как узнать поддерживает ли в принципе Ваш сервер транзакции?
1 2 3 4 5 6 7 8 9 10 |
procedure TMainForm.Button6Click(Sender: TObject); begin if sqlconnection1.Connected then begin if sqlconnection1.TransactionsSupported then showmessage('Поддерживаю транзакции') else showmessage('Не поддерживаю транзакции'); end; end; |
Для сервера MySQL у меня получилось так…
Поддерживает ли Ваш сервер множественные транзакции (несколько в один и тот же момент времени)?
1 2 3 4 5 6 7 8 9 10 |
procedure TMainForm.Button6Click(Sender: TObject); begin if sqlconnection1.Connected then begin if sqlconnection1.MultipleTransactionsSupported then showmessage('Поддерживаю транзакции') else showmessage('Не поддерживаю транзакции'); end; end; |
Для множественных транзакций у сервера MySQL, у меня получилось так…
Как создать транзакцию в Delphi (в технологии DBExpress)?
Как и во многих случаях – путей несколько. Один путь – создать хранимую процедуру на сервере внутри транзакции и из Delphi только вызывать эту хранимую процедуру. Смотрите пример.
Другой путь – создать транзакцию непосредственно в Delphi. Поскольку, я сейчас изучаю DBExpress, буду приводить примеры по созданию транзакций в этой технологии. Насколько, я понял, здесь транзакции могут от одного SQLConnection отправляться только последовательно – это ограничение данной технологии.
На тему создания транзакций, непосредственно из Delphi есть классный узбекский онлайн учебник. Возьму оттуда теоретический пример, а практический построю сам.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var Translnfo: TTransactionDesc; (...) if Not MyConnection.InTransaction then try MyConnection.StartTransaction(Translnfo); {...} MyConnection.Commit(Translnfo); except MyConnection.Rollback(Translnfo); end; |
Что такое TTransactionDesc?
1 2 3 4 5 6 7 8 9 10 11 12 13 |
TTransactionDesc = packed record TransactionID : LongWord; GloballD : LongWord; IsolationLevel : TTransIsolationLevel; Customlsolation : LongWord; при этом TTransIsolationLevel = (xilDIRTYREAD, xilREADCOMMITTED, xilREPEATABLEREAD, xilCUSTOM); |
Что за уровни изоляции такие?
Ранее я писал о них в посте про транзакции и MySQL… Но, в данном посте, позволю себе повториться…
Уровни изоляции транзакций
Итак, для того, чтобы избежать искажения информации при параллельном доступе были разработаны различные уровни изоляции транзакций. Суть в том, чтобы решить те проблемы искажения информации при параллельном доступе, которые были описаны выше.
Read uncommitted (незафиксированное чтение) — наименее защищенный уровень транзакций. Этот уровень рекомендуется исопльзовать только в тех случаях, когда все транзакции работают в режиме чтения.
Read committed (фиксированное чтение) — исключается «грязное чтение», но другим транзакциям разрешено изменять заблокированные строки.
Repeatable read (повторяемое чтение) — накладывает блокировки на обрабатываемые транзакцией строки и не допускает их изменение другими транзакциями, но не запрещает добавление новых записей, что может привести к появлению строк-фантомов. По умолчанию стоит для всех транзакций.
Serializable (сериализуемость) — самый надежный уровень изоляции, полностью исключающий взаимное влияние транзакций.
Покажите пример использования транзакции?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
procedure TMainForm.Button7Click(Sender: TObject); var Translnfo: TTransactionDesc; begin Translnfo.IsolationLevel:=xilREPEATABLEREAD; if Not sqlconnection1.InTransaction then try sqlconnection1.StartTransaction(Translnfo); sqlconnection1.ExecuteDirect('insert into departments(Primary_key,Name,Sort) values(7,''NewRecord'',7)'); sqlconnection1.Commit(Translnfo); except sqlconnection1.Rollback(Translnfo); end; simpledataset1.Refresh; end; |