當多人共用同一記錄時。 |
答題得分者是:P.D.
|
t0288542
中階會員 發表:216 回覆:254 積分:94 註冊:2004-10-06 發送簡訊給我 |
|
christie
資深會員 發表:30 回覆:299 積分:475 註冊:2005-03-25 發送簡訊給我 |
假設要UPDATE TABLE之前先要拿到KEYFLAG
SQL> SELECT * FROM TUPDFLAG; KEYFLAG ------------- 980323 SQL> 舉例 Q1.SQL.Text:=DELETE FROM TUPDFLAG='980323'; Q1.ExecSQL; 也就是說Q1.ROWSAFFECTED >0 的人可以UPDATE TABLE。 ===================引 用 t0288542 文 章=================== 請問各位大大, 如果遇到多個使用者 同時在維護某一表格時,如何去防止 當A或B,同時對某一筆記錄作修改時, A,動作比較快,B再修改後存檔就會有問題, "更新的資料列 最後讀取的值己被變更" 各位大大,有什麼方法可以作。 thks
------
What do we live for if not to make life less difficult for each other? |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
1.不知道你對資料庫的認知有多深
2.不知道你使用的資料庫是那種 通常有以下幾種做法 1.一般稍具規模的資料庫引擎都具有"交易"模式, 進行異動前先啟動交易, 第二個進入者都無法針對該記錄進行異動 2.可以對異動資料庫在異動前, 先標記該筆記錄(以一個實體欄位做flag, 填入一個符號), 當每一個操作者企圖異動該記錄前, 都先檢查該flag的狀況, 當第一個異動者完成或放棄異動時, 由原異動者取消該標記 3.db檔具有自動偵測lock的功能, 所以可以很輕易知道記錄是否被異動 原則上, 所有異動模式, 建議最好在啟動edit 前先檢查記錄是否被人佔用, 而不要在回存時才去做這個動作 ===================引 用 t0288542 文 章=================== 請問各位大大, 如果遇到多個使用者 同時在維護某一表格時,如何去防止 當A或B,同時對某一筆記錄作修改時, A,動作比較快,B再修改後存檔就會有問題, "更新的資料列 最後讀取的值己被變更" 各位大大,有什麼方法可以作。 thks |
t0288542
中階會員 發表:216 回覆:254 積分:94 註冊:2004-10-06 發送簡訊給我 |
|
christie
資深會員 發表:30 回覆:299 積分:475 註冊:2005-03-25 發送簡訊給我 |
------
What do we live for if not to make life less difficult for each other? |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
這的確是一個很大的難題, 因為 資料庫都有BUFFER的問題, 也就是一旦A,B,都載入記錄後, A異動並不會影響B, 因為如果會影響的話, 可能會造成世界大戰, 所以我能想到的一個辦法是利用 SOCKETSERVER, SOCKETCLIENT 來互相傳遞消息, 也就是當 A 異動儲存完成, 由 A 電腦發訊息(A當CLEINT)到 B 電腦(B當 SERVER), 當B收到訊息後, 重新 UPDATE 現在的資料庫, 但這當中又牽涉到太多的技術及KNOWHOW, 例如 如果 B正在編輯當中怎麼辦, 如果B 所SELECT 的範圍與 A 更新的記錄並無任何關係時, 如何做, 如果 B 沒有在資料庫中, 如果 不只 B電腦, 可能線上有10台, 20台在操作, 又怎麼辦? 當然還有更多的問題, 哦~~~我實在不敢想, 所以最簡單的方式是採被動執行, 不要去想主動這檔事吧!
===================引 用 t0288542 文 章=================== 謝謝 christie 及 P.D. 兩位大大。 如以設 flag 欄位作判斷,我又想到一個問題, 當 A,B都同時停留在這一筆記錄查詢畫面,A動作快鎖定修改也作存檔,但B的畫面值沒有作同步, 那這種情況如何去解決呢,在修改時 畫面的值 和 資料庫的值 在一一比對,告訴B資料已被修改請重新作查詢動作。 請問各位大大,有什麼方法可解決。 麻煩大家。thks |
t0288542
中階會員 發表:216 回覆:254 積分:94 註冊:2004-10-06 發送簡訊給我 |
|
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
t0288542
中階會員 發表:216 回覆:254 積分:94 註冊:2004-10-06 發送簡訊給我 |
|
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
jackiemi2_seed
中階會員 發表:37 回覆:97 積分:76 註冊:2006-09-11 發送簡訊給我 |
id name addr
0001 大毛 美國 id為pk欄位 把大毛修改成二毛, update table_a set name='二毛' where id='0001' and name='大毛' 下指令儲存時把修改的欄位及pk欄位加入where條件, 這樣就可以避免有人先把資料修改了 但要記得判斷修改筆數是否為1, powerbuild的datastore的update設定有這個選項可以選,滿利害的 不知delphi有沒有類似的東西 ===================引 用 t0288542 文 章=================== 請問各位大大, 如果遇到多個使用者 同時在維護某一表格時,如何去防止 當A或B,同時對某一筆記錄作修改時, A,動作比較快,B再修改後存檔就會有問題, "更新的資料列 最後讀取的值己被變更" 各位大大,有什麼方法可以作。 thks
------
OS : Win 7 pro Program : Delphi 7 DataBase : Ms Sql 2008 |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
我在 Delphi - Midas 基础上来讨论这个问题。假设大家熟悉 Midas:
Midas,也就是后来的 DataSnap 架构,简单点说,就是 Delphi 提供的 3 层架构,类似这样的架构: Connection - DataSet - DataSetProvider --- 3层连接诸如 SocketServer 或者甚至是 WebService --- Client 端的 ClientDataSet --- Datasource --- DBGrid 在这个架构下,需要注意的观念是:客户端也就是 Client 端,每次从 SERVER 端取完数据后,就断开连接,是【非状态】的,也就是服务器端不保存客户端的状态。当然,MIDAS 也支持服务器端保存客户端的状态的方式,但这样的方式不好,客户端很多的时候,服务器端会压力很大。 在上述观念下,假设有 2 个客户端,都从服务器端取得了同一个 TABLE 的数据到客户端的 ClientDataSet 里,并显示到 DBGird 里,假设 DATA 如下: ID Name Age 1 Jack 26 2 Rose 28 假设有这么两条 RECORD 同时在客户端 A 和客户端 B。假设 A 把 JACK 的 AGE 从 26 修改为 29; B 把 JACK 的 AGE 从 26 修改为 25。修改完后,当然要提交。这个时候,程序该如何处理? 这样的情况下,首先要考虑的是你的程序提供什么样的逻辑给用户。逻辑可能有多种,比如: 1. 以最后修改的为准; 2. 如果别人修改过了,必须看到最新的结果后,再考虑是否可以再次修改; 3. 如果别人已经修改过,则不能进行修改; 上面 3 种逻辑,都是可能的,看你采用哪一种。也许还有其它的逻辑规则呢,也说不定。看你的客户要求是什么了。 那上述假设里,A 和 B 就算同时按下提交按钮,也可能是 A 先提交,也可能是 B 先提交。不管谁先提交,后提交者面临一个问题:那条记录,在 DataBase 里面,AGE 已经和原来不一样了! 而 DELPHI 的 DataSnap 则提供了各种控制提交的可能。比如要实现逻辑 1,以最后修改的为准,如果按照 MIDAS 的默认设置,后提交者会提交失败的。因为默认设置,MIDAS 的 SERVER 端的 DataSetProvider 会去和 DataBase 里的同一条记录做比对,如果不同,则不会提交。会返回提交错误给客户端。按照逻辑 1,我需要不管那条记录是否已经被别人修改,都可以提交。那么,更改 DataSetProvider 的属性,设置为只以 Primary Key 为准,则 DataSetProvider 会从 DataBase 里用客户端提交记录的 Primary Key 来搜索那条记录,搜索到,则 Update 该记录,提交成功。 如果采用逻辑2,那么: DataSetProvider 的默认属性,是以所有 Field 为条件去 select 该记录,后提交者提供的该记录的原始记录是 1, Jack, 26,而 DataBase 里该记录可能是 1, Jack, 28,那么,DataSetProvider 搜索不到正确的记录,就不会真正提交修改后的数据给 DataBase ,而会返回异常给客户端了。这时候,客户端可以在 clientDataSet 的 ReconcileError 事件里,进行相应的处理。比如提示用户该记录已经被修改过了,是否仍然要提交(也就是覆盖了前人的修改),还是放弃提交,等。 如果采用逻辑3,则仍然采用默认属性设置,提交失败则提示用户,然后直接放弃提交就可以了 --- 这里,放弃掉提交后,需要把用户当前的数据比如 1, Jack, 26 刷新为 DataBase 里最新的数据比如 1, Jack, 28,最简单的是 ClientDataSet.Refresh 一下。当然,为了效率,可以做得更复杂一些,仅仅是从 Server 端取回这一条记录。这里又涉及到其它一些 ClientDataSet 使用上的观念和技巧了。对于这些技巧,如果有需要,我们可以假设一种具体的案子,然后可以进一步讨论。 总之,搞清楚 MIDAS 的工作原理,就很容易想到类似情况该如何处理了。搞清楚的办法,我比较笨,是在提交的时候,直接设置断点,跟踪 DataSetProvider 内部的代码,看它每一步是如何处理的。 ===================引 用 P.D. 文 章=================== 以timer當然是可以的, 這是由client 各自發起的thread來重新 reload 資料庫, 但要注意的是, 要加入判斷目前pc正在做啥事的功能, 否則這台正在更新資料, 你的timer給 reflash 的話, 那使用者會出 "國罵" 的 ===================引 用 t0288542 文 章=================== 略.... 我的想法是在放個 timer 一段時間,重新整理一下。不知是否ok. 麻煩大家,thks |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |