在主行程和執行緒中都操作了資料庫,子執行緒是重新創建連接來處理的,在這種情況下,想實作只要一個錯誤全部回滾,也就是事務的功能。
或者這個問題也可以說和多執行緒無關,就是一個程式中創建了多個連接,在同時利用多個連接操作資料庫的情況下,怎么實作事務功能?
uj5u.com熱心網友回復:
你的連接是DataSnap C/S,還是直接連接本地資料庫。uj5u.com熱心網友回復:
用ado連的c/s資料庫uj5u.com熱心網友回復:
事務處理需要利用Delphi的相關控制元件或資料庫管理軟體進行。它應是由數個SQL陳述句組成,要求同時正確執行。只要有一條失誤,全部取消。樓主提出的方案,在不同的執行緒(不同的連接)中代碼,構成事務,好象不可取。尚未見到實體。
構成事務的幾個SQL陳述句,是抱團執行,不好分割。建議利用ADO提供的事務處理功能
adoconnection1.begintrans; // 開始事務try adoconnection1.execute(sqlstr1); adoconnection1.execute(sqlstr2); ... adoconnection1.execute(sqlstrN); adoconnection1.commitrans; // 提交事務 showmessage('操作成功');except adoconnection1.rollbacktrans; // 事務回滾 showmessage('操作失敗');end;如果需要執行緒,可以將上述代碼裝進一個執行緒中執行。
uj5u.com熱心網友回復:
adoconnection1.begintrans; // 開始事務
try
adoconnection1.execute(sqlstr1);
adoconnection1.execute(sqlstr2);
...
adoconnection1.execute(sqlstrN);
adoconnection1.commitrans; // 提交事務
showmessage('操作成功');
except
adoconnection1.rollbacktrans; // 事務回滾
showmessage('操作失敗');
end;
uj5u.com熱心網友回復:
謝謝樓上,這個方法我是知道的。我最近在考慮用rtc做應用服務器,也在應用服務器上肯定不能給每個客戶端連接都建一個持久的connection的,要使用連接池的方式,這就意味著客戶端執行多個 execsql 時,有可能每個執行用的不是同一個 connection,這個時候,就不知道事務怎么處理了!uj5u.com熱心網友回復:
一般情況下,c/s 方式,在客戶端可以使用如下類似陳述句來管理事務:begintran;
execsql(...);
execsql(...);
committran;
但是,如果是連接應用服務器的情況(或者在利用多執行緒執行 execsql),因為沒法確保每次 execsql 均使用同一個 connection ,這就造成了 begintran 沒法用。所以就問這個問題,是不是多個 connection 沒法使用同一個事務,只能想辦法避免是吧?
uj5u.com熱心網友回復:
連接池?咋不用FireDAC、DataSnap技術
uj5u.com熱心網友回復:
多執行緒內是獨立的會話連接,也可以并行執行或查詢sql陳述句,就是不能用事務。uj5u.com熱心網友回復:
你想每個連接都有事務的功能,只能回圈在主執行緒內跑。uj5u.com熱心網友回復:
出個騷主意,sql你可以定位一個結構體,結構體內有標志位等,主執行緒內一直回圈查詢標志位從而實作假的并發,但是這樣子就可以使用事務了,有點子執行緒池的味道。主執行緒內只干這事,其他業務交給子執行緒,子執行緒和主執行緒通過windows訊息的wm_copydata傳遞資料,或者以事件通知的方式。
uj5u.com熱心網友回復:
這樣的啊,你把那個連接物件封一下,加一個是否執行成功屬性,自己寫一個exec方法,在執行sql之前都開戶事務(這里開啟事務、提交事務都可以單獨寫成方法),同是回傳那個連接物件,及改變(是否執行成功屬性)的值(現在假設失敗為false);呼叫;
con1:=exec(sql1);
con2:=exec(sql2);
con3:=exec(sql3);
con4:=exec(sql4);
b:=con1.flag and con2.flag and con3.flag and con4.flag;
//以下可以寫成通用方法,如陣列,集合之類,統一處理。
if b then
begin
con1.commit;
con2.commit;
con3.commit;
con4.commit;
end
else
begin
con1.rollback();
con2.rollback();
con3.rollback();
con4.rollback();
end;
uj5u.com熱心網友回復:
不影響,事務由資料庫自己保證的。公開給客戶端的介面只是連接,至于你客戶端自己的編程模式沒有影響。uj5u.com熱心網友回復:
你的結構有問題吧,多執行緒連接只是為了提高速度,沒辦法一個用戶用到多個連接。建立執行緒詞,用戶請求加入執行緒任務佇列,保證同一個邏輯程序由同一個執行緒處理,當然也就可以用事務了。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/80251.html
標籤:語言基礎/算法/系統設計
