請問多筆資料插入時出錯如何恢復? |
答題得分者是:bestlong
|
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
|
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
|
bestlong
站務副站長 發表:126 回覆:734 積分:512 註冊:2002-10-19 發送簡訊給我 |
|
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
|
tech_state
版主 發表:44 回覆:638 積分:641 註冊:2003-02-10 發送簡訊給我 |
ADOConnection1->BeginTrans(); // 交易機制開始 try { ... ADOConnection1->CommitTrans(); // 交易機制完成 } catch(...) { ADOConnection1->RollbackTrans(); // 交易機制回復資料 ShowMessage("database insert fail"); }Good Lucky !! ================================= 涵養怒中氣。謹防順口言。留心忙裡錯。珍惜有時錢。 是非終日有,不聽自然無 天下本無事,庸人自擾之 |
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
AnsiString cmd; try { cmd = "insert into Table_A (SN) values('12345')"; ADOConnection1->BeginTrans(); ADOQuery1->Close(); ADOQuery1->SQL->Clear(); ADOQuery1->SQL->Add(cmd); ADOQuery1->ExecSQL(); } catch(Exception &e) { ADOConnection1->RollbackTrans(); ShowMessage(cmd); return; } try { cmd = "insert into Table_B (SN, Text) values('12345', 'ABC')"; ADOQuery1->Close(); ADOQuery1->SQL->Clear(); ADOQuery1->SQL->Add(cmd); ADOQuery1->ExecSQL(); ADOConnection1->CommitTrans(); } catch(Exception &e) { ADOConnection1->RollbackTrans(); ShowMessage(cmd); return; }請問如果當Table_B插入出現錯誤時,為什麼Table_A的記錄不會清除掉? |
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
AnsiString cmd; try { cmd = "select * from Table_A where SN='12345'"; ADOQuery1->Close(); ADOQuery1->SQL->Clear(); ADOQuery1->SQL->Add(cmd); ADOQuery1->Open(); } catch(Exception &e) { ShowMessage(cmd); ShowMessage(e.Message.c_str()); return; } try { if(ADOQuery1->RecordCount) { ADOQuery1->Edit(); ADOQuery1->FieldByName("Date")->AsString = FormatDateTime("YYYY-MM-DD HH:MM:SS", Now()); } else { ADOQuery1->Append(); ADOQuery1->FieldByName("SN")->AsString = "12345"; ADOQuery1->FieldByName("Date")->AsString = FormatDateTime("YYYY-MM-DD HH:MM:SS", Now()); } } catch(Exception &e) { ShowMessage(cmd); ShowMessage(e.Message.c_str()); return; } try { cmd = "select * from Table_B"; ADOQuery2->Close(); ADOQuery2->SQL->Clear(); ADOQuery2->SQL->Add(cmd); ADOQuery2->Open(); } catch(Exception &e) { ShowMessage(cmd); ShowMessage(e.Message.c_str()); return; } try { ADOTable1->First() for(int i = 0; i < ADOTable1->RecordCount; i ) { ADOQuery2->Append(); ADOQuery2->FieldByName("SN")->AsString = ADOTable1->FieldByName("SN")->AsString; ADOQuery2->FieldByName("ID")->AsString = ADOTable1->FieldByName("Id")->AsString; ADOQuery2->FieldByName("NUM")->AsInteger = ADOTable1->FieldByName("Num")->AsInteger; ADOTable1->Next(); } } catch(Exception &e) { ShowMessage(cmd); ShowMessage(e.Message.c_str()); return; } try { ADOConnection1->BeginTrans(); ADOQuery1->UpdateBatch(arAll); ADOQuery2->UpdateBatch(arAll); ADOConnection1->CommitTrans(); } catch(Exception &e) { ADOConnection1->RollbackTrans(); ShowMessage(e.Message.c_str()); return; }以上ADOQuery的LockType皆設為ltBatchOptimistic。 這樣做的話,Table_B插入時出錯就可以恢復原狀。 但是為啥Table_A恢復不了?即使Table_A語法沒錯也應該恢復不是嗎? |
bestlong
站務副站長 發表:126 回覆:734 積分:512 註冊:2002-10-19 發送簡訊給我 |
|
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
抱歉,上面是我憑記憶寫出來的,下面才是真正的。
//--------------------------------------------------------------------------- #includetable_a: create table Table_A ( SN varchar(20) not null, Date varchar(20), primary key(SN) ); table_b: create table Table_B ( SN varchar(20) not null, ID varchar(20) not null, NUM int, primary key(SN, ID) ); table_c: create table Table_C ( SN varchar(20), ID varchar(20), NUM int ); insert into table_c (sn, id, num) values('123', 'abc', 10); insert into table_c (sn, id, num) values('123', 'def', 20); insert into table_c (sn, id, num) values('123', 'ghi', 30); insert into table_c (sn, id, num) values('456', 'abc', 40); insert into table_c (sn, id, num) values('456', 'def', 50); insert into table_c (sn, id, num) values('456', 'ghi', 60); insert into table_c (sn, id, num) values('789', 'abc', 70); insert into table_c (sn, id, num) values('789', 'def', 80); insert into table_c (sn, id, num) values('789', 'ghi', 90); insert into table_c (sn, id, num) values('789', 'jkl', 100); ADOConnection1 -> ADOTable1 ADOConnection2 -> ADOQuery1, ADOQuery2 ADOquery1, ADOQuery2的LockType為ltBatchOptimistic 執行步驟:BitBtn1 -> BitBtn2 -> BitBtn1 小弟故意利用此問題來查看table是否會恢復原狀。 但結果卻還是照樣更新了。 |
bestlong
站務副站長 發表:126 回覆:734 積分:512 註冊:2002-10-19 發送簡訊給我 |
引言: 執行步驟:BitBtn1 -> BitBtn2 -> BitBtn1 小弟故意利用此問題來查看table是否會恢復原狀。 但結果卻還是照樣更新了。首先 ADOTable1 不知道你是設定連接 Table_b 還是 Table_c. 所以不確定你所說的故意利用此問題是想產生什麼樣的錯誤. 按下 BitBtn1 如果沒有發生錯誤就一定會更新回資料庫 因為已經 CommitTrans 既然更新了當然就無法回復. 按下 BitBtn2 也是直接更新回資料庫, 也不能回復. 感覺起來好像你對 Transation 的觀念還不夠清楚, 建議你再深入研究一下. 我是雪龍 發表人 - bestlong 於 2005/01/28 09:04:06
------
http://blog.bestlong.idv.tw/ http://www.bestlong.idv.tw/ http://delphi-ktop.bestlong.idv.tw/ |
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
您好。
按下第一次BitBtn1時,正常是不會出現錯誤,內容如下:
mysql> select * from table_a;
----- ---------------------
| SN | Date |
----- ---------------------
| 123 | 2005-01-28 09:32:07 |
| 456 | 2005-01-28 09:32:07 |
| 789 | 2005-01-28 09:32:07 |
----- ---------------------
3 rows in set (0.13 sec) mysql> select * from table_b;
----- ----- ------
| SN | ID | NUM |
----- ----- ------
| 123 | abc | 10 |
| 123 | def | 20 |
| 123 | ghi | 30 |
| 456 | abc | 40 |
| 456 | def | 50 |
| 456 | ghi | 60 |
| 789 | abc | 70 |
| 789 | def | 80 |
| 789 | ghi | 90 |
| 789 | jkl | 100 |
----- ----- ------
10 rows in set (0.01 sec) mysql> select * from table_c;
------ ------ ------
| SN | ID | NUM |
------ ------ ------
| 123 | abc | 10 |
| 123 | def | 20 |
| 123 | ghi | 30 |
| 456 | abc | 40 |
| 456 | def | 50 |
| 456 | ghi | 60 |
| 789 | abc | 70 |
| 789 | def | 80 |
| 789 | ghi | 90 |
| 789 | jkl | 100 |
------ ------ ------
10 rows in set (0.00 sec) 按下第一次BitBtn2時,也是沒問題,內容如下:
mysql> select * from table_a;
----- ---------------------
| SN | Date |
----- ---------------------
| 123 | 2005-01-28 09:32:07 |
| 456 | 2005-01-28 09:32:07 |
| 789 | 2005-01-28 09:32:07 |
----- ---------------------
3 rows in set (0.00 sec) mysql> select * from table_b;
----- ----- ------
| SN | ID | NUM |
----- ----- ------
| 123 | abc | 10 |
| 123 | def | 20 |
| 123 | ghi | 30 |
| 456 | abc | 40 |
| 456 | def | 50 |
| 456 | ghi | 60 |
| 789 | abc | 70 |
| 789 | def | 80 |
| 789 | ghi | 90 |
| 789 | jkl | 100 |
----- ----- ------
10 rows in set (0.00 sec) mysql> select * from table_c;
------ ------ ------
| SN | ID | NUM |
------ ------ ------
| test | test | 1000 |
| 123 | def | 20 |
| 123 | ghi | 30 |
| 456 | abc | 40 |
| 456 | def | 50 |
| 456 | ghi | 60 |
| 789 | abc | 70 |
| 789 | def | 80 |
| 789 | ghi | 90 |
| 789 | jkl | 100 |
------ ------ ------
10 rows in set (0.00 sec) 按下第二次BitBtn1時就出現問題了,內容如下:
Warning: Some non-transaction changed tables coundn't be rolled back. mysql> select * from table_a;
------ ---------------------
| SN | Date |
------ ---------------------
| 123 | 2005-01-28 09:35:57 | <----- Date應該是2005-01-28 09:32:07
| 456 | 2005-01-28 09:35:57 | <----- Date應該是2005-01-28 09:32:07
| 789 | 2005-01-28 09:35:57 | <----- Date應該是2005-01-28 09:32:07
| test | 2005-01-28 09:35:57 | <----- 這裡記錄不應該出現的
------ ---------------------
4 rows in set (0.00 sec) mysql> select * from table_b;
------ ------ ------
| SN | ID | NUM |
------ ------ ------
| 123 | abc | 10 |
| 123 | def | 20 |
| 123 | ghi | 30 |
| 456 | abc | 40 |
| 456 | def | 50 |
| 456 | ghi | 60 |
| 789 | abc | 70 |
| 789 | def | 80 |
| 789 | ghi | 90 |
| 789 | jkl | 100 |
| test | test | 1000 | <----- 這筆記錄不應該出現的
------ ------ ------
11 rows in set (0.00 sec) mysql> select * from table_c;
------ ------ ------
| SN | ID | NUM |
------ ------ ------
| test | test | 1000 |
| 123 | def | 20 |
| 123 | ghi | 30 |
| 456 | abc | 40 |
| 456 | def | 50 |
| 456 | ghi | 60 |
| 789 | abc | 70 |
| 789 | def | 80 |
| 789 | ghi | 90 |
| 789 | jkl | 100 |
------ ------ ------
10 rows in set (0.00 sec) 請幫我看看哪裡出錯了?
|
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
小弟是用 BCB6 SP4
MySQL v3.2358
MyODBC 3.51.04 執行第二次BitBtn1時會出現以下錯誤:
[MySQL][MyODBC 3.51Driver]Warning: Some non-transactional changed tables couldn't be rolled back. 請問是不是MyODBC不支援有關?還是MySQL不支援Transaction?還是ODBC不支援Transaction? 可不可以給小第一個簡單的範例參考一下?或是哪裡可以讓小弟學習Transaction機制?
|
irvinehing
初階會員 發表:77 回覆:79 積分:31 註冊:2003-11-12 發送簡訊給我 |
終於解決了。
MySQL 3.23-max的InnoDB才支援Transaction,所以只要把MySQL安裝成mysqld-max,再設定my.ini就好了。 步驟一:
mysqld-max --install 步驟二:
[mysqld]
# You can write your other MySQL server options here
# ...
# Data files must be able to hold your data and indexes.
# Make sure that you have enough free disk space.
innodb_data_file_path = ibdata1:10M:autoextend
#
# Set buffer pool size to 50-80% of your computer's memory
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
#
# Set the log file size to about 25% of the buffer pool size
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
#
innodb_flush_log_at_trx_commit=1 步驟三:
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) ENGINE=InnoDB;
或
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) TYPE=InnoDB;
|
bestlong
站務副站長 發表:126 回覆:734 積分:512 註冊:2002-10-19 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |