here are four isolation levels:
SQL server實現(xiàn)了四個級別
Oracle只實現(xiàn)中間兩個級別。
文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414835.aspx
here are four isolation levels:
我們一般項目中,都是把字典存到數(shù)據(jù)庫中的。幾個月前在做一個政府的項目中,覺得其實一些字典是跟開發(fā)工程緊密結合在一起的,也就是說字典變了,工程肯定也要變,這樣子的字典如果也存到數(shù)據(jù)庫中的話,也是多增加一些麻煩而已,后來但將這些字典寫成枚舉。然后數(shù)據(jù)庫里面取的所謂的字典的key就是枚舉的name,如:"unsubmited",而前臺頁面顯示的,就是枚舉的一個屬性text,不過這里用到了webwork里面的ognl語法。
前幾天同事講了Transaction isolation level,并且大家一起在SQLServer,Oracle跟MySQL數(shù)據(jù)庫上實驗了一下,發(fā)覺這些知識還是挺重要的。
假如有兩個事務并發(fā),順序如下
Transaction A Transaction B
begin begin
query1 from table A
....... modify1 to table A(insert/update/delete)
commit
query2 from table A
commit
那么在事務A中,query1跟query2查詢出來的結果是否一樣呢?這就跟事務隔離級別有關了。
SQL的標準定義里面,一共有四種級別:
read uncommited讀取未提交的數(shù)據(jù) 就是其他事務求提交的數(shù)據(jù),都可以讀取出來
read commited讀取已提交的數(shù)據(jù) query2會跟query1讀取的數(shù)據(jù)不一樣
repeatable read可重復讀取,即query1跟query2讀取的數(shù)據(jù)是一樣的
serializable 序列化,
SQL 標準用三個必須在并行的事務之間避免的現(xiàn)象定義了四個級別的事務隔離。 這些不希望發(fā)生的現(xiàn)象是:
臟讀(dirty reads)
一個事務讀取了另一個未提交的并行事務寫的數(shù)據(jù)。
不可重復讀(non-repeatable reads)
一個事務重新讀取前面讀取過的數(shù)據(jù), 發(fā)現(xiàn)該數(shù)據(jù)已經(jīng)被另一個已提交的事務修改過。
幻讀(phantom read)
一個事務重新執(zhí)行一個查詢,返回一套符合查詢條件的行, 發(fā)現(xiàn)這些行因為其他最近提交的事務而發(fā)生了改變。
隔離級別 臟讀(Dirty Read) 不可重復讀(NonRepeatable Read) 幻讀(Phantom Read)
讀未提交(Read uncommitted) 可能 可能 可能
讀已提交(Read committed) 不可能 可能 可能
可重復讀(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能
SQLServer
我們首先在SQLServer上做了實驗,SQLServer一共支持四種隔離級別,read uncommited跟read commited我們沒有實驗,我們直接先實驗
repeatable read,如果事務A定義了如下級別,那么當事務B執(zhí)行到modify1這條語句時,如果modify1是update的話,就被鎖起來,一直等
到事務A提交完以后,鎖才會被釋放,而如果是insert的話,剛可以順利進行下去,然后在事務A中,query2查到的數(shù)據(jù),是已經(jīng)被事務B
修改過的數(shù)據(jù),如果將級別定義在serializable的話,則在modify1語句中,update,insert或者delete都會被鎖掉。
也就是說,SQLServer對這些級別的支持,是通過鎖來做到的,雖然可以保證事務正常進行,但是并行的性能卻很差。
Oracle
oracle只支持兩個級別,read commited跟serializable,結果這里就不用詳細說明,實驗的結果是,oracle的serializable是通過版本
控制來完成的,而不是通過鎖機制,這就保證了并行的性能。Oracle的默認級別是read commited
MySQL
MySQLServer也支持四個級別,而且MySQL也是通過版本控制而非鎖機制來完成的。
其實這種事情都會有兩個觀點。
一個觀點是:建議使用自己熟悉的技術,采用簡單的架構去實現(xiàn)項目,等到你把項目做出來了,能用起來了,客戶認可了。以后的升級,那是你就可以比較輕松的采用其 它的架構來重構,這樣你的風險,壓力就相對減少很多了。
而這回,我想頂一下第二個觀點:
其實如果你對代碼要求比較嚴格的話,你就會經(jīng)常發(fā)現(xiàn),你的代碼有很多東西可以抽取出來,或者做在公共的模塊,或者作為框架的底層,我們就簡單的拿jdbc來說吧,
首先,是connection的管理,這點一般用jdbc熟一些的話,都會有管理connection的公共模塊,雖然偶爾會碰到性能的問題,但是這點我們暫且壓下不表。
我們查詢的時候,每次都要用
rs.get...("name"),
rs.get...("id"),
rs.get...("age"),
rs.get...("gender"),
rs.get...("hobby"),
然后修改數(shù)據(jù)庫的時候,還要拼寫update語句跟insert語句,經(jīng)常還要費很多時間來調試這些多余代碼的問題,這時候你就想,不行,我一定要寫一個公共模塊,省得讓我每次都要定這么多代碼,于是你的第一個公共模塊產生了,然后測試啊測試,改進啊改進,叮叮響,過了幾天時間的考驗,這個公共模塊終于可以放心使用了,項目進度開始快一些了,總算不用再拼SQL了。
后來在做統(tǒng)計模塊的時候,突然又發(fā)現(xiàn),之前在用到的一些SQL函數(shù),好像在客戶要求的數(shù)據(jù)庫上不怎么行啊,于是又去查了一下資料,又過了幾天(可能這次不用幾天),然后終于放心,所有的函數(shù)都正常了。
接著又不可避免的碰到了分頁的問題,你對自己說,不用怕,我上回就寫了一個分頁的,沒有問題!可是Ya的你突然發(fā)現(xiàn),上回的那個分頁是用游標實現(xiàn)的,這回客戶是要求用SQLServer,唉,SQLServer的游標,不提也罷,想來想去,只好自己拼SQL語句來寫分頁了,又是count又是top,測了又測之后,又過了幾天,啊哈,終于分頁的公共模塊也做好的,可以放心使用了,好,項目的進度又可以加快了。
做著做著的時候,發(fā)現(xiàn),咦,好像這表得增加一個字段才行,增加了,然后所有查詢的SQL語句加一下,所有insert跟update的代碼修改一下,頁面修改一下,嗯,現(xiàn)在應該正常了,看起來倒是沒什么問題,咦,報表好像不怎么對啊,靠,這邊還有調用這個表的代碼,媽的,改吧改吧。磨蹭了好幾個小時(當然,熟練的話,并不用幾個小時),總算看起來都正常了。
這一回,這個功能中有一次用戶請求,訪問了好幾次數(shù)據(jù)庫,不行,這里應該用個cache,否則性能上會有問題啊,算了,用算法解決一下,盡量少訪問數(shù)據(jù)庫好了,我對cache還不熟呢。(寫啊寫啊,Batch Size,這樣多,那樣多,F(xiàn)etch Size。。。,終于,看起來正常一些了)。過了一段時間,靠,這邊又要訪問好幾次數(shù)據(jù)庫,Ya的受不鳥了,性能愛咋的咋的,反正一個地方慢又不要緊。Oh shit!!!這邊也是好幾次,這邊又是好幾次,那邊又是好幾次。不行了,我老老實實寫個cache支持吧,于是又叮叮當當了好幾天,終于,有個粗糙的cache出來了,終于速度可以看一些了。后來改進又改進,測試又測試,累死了,老子好不爽啊。
好像天下有點太平了,啊,你說我這個地方忘記更新你增加的那個子表啊,算了,沒關系,我明天看一下代碼,這個容易解決點。嗯,我改了那邊的代碼了,會更新子表信息了。什么?你說取主表的記錄跟相應的子表記錄列表麻煩啊,沒關系,我更新一下處理resultset的公共模塊,明天再說。
Oh shit......對這樣子復雜的查詢好像現(xiàn)在的公共模塊支持不了啊,算了,這樣子的查詢不要用這個公共模塊,我們手動寫一些代碼好啊,別跟我講這樣代碼結構很難看,你以為我不知道啊,TMD。
TMD的,怎么這邊的SQL老是運行不了啊,不會是分頁底層模塊的問題吧,靠,怎么你的SQL語句有這么多order,group by,靠,還有top啊,這當然過不了了,不要吵了,現(xiàn)在時間改,不理它,直接用個假分頁就行了。你又說代碼結構難看,小心我抽你哦。
公司新來一個程序員,看了幾天代碼,不停的抱怨說,這代碼寫得真差啊。。。。。。
目前jQuery網(wǎng)站上已經(jīng)有了From的驗證框架,F(xiàn)romValidation,但是一直覺得它的框架并不好用,因為重復寫的東西太多了。
于是就再次寫了自己的JavaScript驗證框架,完全廢棄掉以前的。
在新的框架下,是以這樣子的用法設計的:
首先,要包括自己的js文件(這點不必說),而且在包括自己寫,要先包括jQuery的,如下
然后在要驗證的Form里面加個屬性validatable=true,如下:
注意,這邊不要加onsubmit方法
接下來,就好了,比如說有個輸入框:
<ww:textfield name="name" id="name"/>
我想驗證,讓它必填,如下就可以了:
<label for="name" validate="required">請?zhí)顚懨Q</label> 其中 for屬性里面填的要是驗證的輸入框id,validate填的是驗證方法,;label里面的文本就是驗證不過的時候要顯示的信息。
如果我想驗證一個輸入框的輸入值長度怎么辦,這樣子就行了
后面的參數(shù)用;號隔開,驗證的方法名跟參數(shù)用: 隔開。
wingel.js里面已經(jīng)包括了一些常用的驗證方法,現(xiàn)在問題來了,如果要自定義驗證方法怎么辦,如下辦:
比如你想加個驗證方法是hello
則label里面的validate屬性寫成hello,
然后加一個JavaScript方法:
里面三個參數(shù),shit , couldn't input Chinese. now English will be used.
The first parameter is the value of the input element you want to validate,the second one is the validated element, the third one, is the parameters you add in validate label, the last one, is a utility class, you can invoke its method to make your code easier.