#
什么是HTTP Referer
簡(jiǎn)言之,HTTP
Referer是header的一部分,當(dāng)瀏覽器向web服務(wù)器發(fā)送請(qǐng)求的時(shí)候,一般會(huì)帶上Referer,告訴服務(wù)器我是從哪個(gè)頁(yè)面鏈接過(guò)來(lái)的,服務(wù)器
籍此可以獲得一些信息用于處理。比如從我主頁(yè)上鏈接到一個(gè)朋友那里,他的服務(wù)器就能夠從HTTP
Referer中統(tǒng)計(jì)出每天有多少用戶(hù)點(diǎn)擊我主頁(yè)上的鏈接訪問(wèn)他的網(wǎng)站。
Referer其實(shí)應(yīng)該是英文單詞Referrer,不過(guò)拼錯(cuò)的人太多了,所以編寫(xiě)標(biāo)準(zhǔn)的人也就將錯(cuò)就錯(cuò)了。
我的問(wèn)題
我剛剛把feed閱讀器改變?yōu)?a >Gregarius,但他不像我以前用的liferea,訪問(wèn)新浪博客的時(shí)候,無(wú)法顯示其中的圖片,提示“此圖片僅限于新浪博客用戶(hù)交流與溝通”,我知道,這就是HTTP Referer導(dǎo)致的。
由于我上網(wǎng)客戶(hù)端配置的特殊性,首先懷疑是squid的問(wèn)題,但通過(guò)實(shí)驗(yàn)排除了,不過(guò)同時(shí)發(fā)現(xiàn)了一個(gè)Squid和Tor、Privoxy協(xié)同使用的隱私泄露問(wèn)題,留待以后研究。
Gregarius能處理這個(gè)問(wèn)題么?
答案是否定的,因?yàn)镚regarius只是負(fù)責(zé)輸出html代碼,而對(duì)圖像的訪問(wèn)是有客戶(hù)端瀏覽器向服務(wù)器請(qǐng)求的。
不過(guò),安裝個(gè)firefox擴(kuò)展也許能解決問(wèn)題,文中推薦的”Send Referrer”我沒(méi)有找到,但發(fā)現(xiàn)另外一個(gè)可用的:”RefControl“,可以根據(jù)訪問(wèn)網(wǎng)站的不同,控制使用不同的Referer。
但是我不喜歡用Firefox擴(kuò)展來(lái)解決問(wèn)題,因?yàn)槲矣X(jué)得他效率太低,所以我用更好的方式——Privoxy。
Privoxy真棒
在Privoxy的default.action中添加兩行:
{+hide-referrer{forge}}
.album.sina.com.cn
這樣Gregarius中新浪博客的圖片就出來(lái)了吧?+hide-referrer
是Privoxy的一個(gè)過(guò)濾器,設(shè)置訪問(wèn)時(shí)對(duì)HTTP Referer的處理方式,后面的forge
代表用訪問(wèn)地址當(dāng)作Refere的,還可以換成block
,代表取消Referer,或者直接把需要用的Referer網(wǎng)址寫(xiě)在這里。
用Privoxy比用Firefox簡(jiǎn)單的多,趕緊換吧。
From https to http
我還發(fā)現(xiàn),從一個(gè)https頁(yè)面上的鏈接訪問(wèn)到一個(gè)非加密的http頁(yè)面的時(shí)候,在http頁(yè)面上是檢查不到HTTP Referer的,比如當(dāng)我點(diǎn)擊自己的https頁(yè)面下面的w3c xhtml驗(yàn)證圖標(biāo)(網(wǎng)址為http://validator.w3.org/check?uri=referer),從來(lái)都無(wú)法完成校驗(yàn),提示:
No Referer header found!
原來(lái),在http協(xié)議的rfc文檔中有定義:
15.1.3 Encoding Sensitive Information in URI's
...
Clients SHOULD NOT include a Referer header field in a (non-secure)
HTTP request if the referring page was transferred with a secure
protocol.
這樣是出于安全的考慮,訪問(wèn)非加密頁(yè)時(shí),如果來(lái)源是加密頁(yè),客戶(hù)端不發(fā)送Referer,IE一直都是這樣實(shí)現(xiàn)的,Firefox瀏覽器也不例外。但這并不影響從加密頁(yè)到加密頁(yè)的訪問(wèn)。
Firefox中關(guān)于Referer的設(shè)置
都在里,有兩個(gè)鍵值:
-
network.http.sendRefererHeader (default=2)
設(shè)置Referer的發(fā)送方式,0為完全不發(fā)送,1為只在點(diǎn)擊鏈接時(shí)發(fā)送,在訪問(wèn)頁(yè)面中的圖像什么的時(shí)候不發(fā)送,2為始終發(fā)送。參見(jiàn)Privacy Tip #3: Block Referer Headers in Firefox
-
network.http.sendSecureXSiteReferrer (default=true)
設(shè)置從一個(gè)加密頁(yè)訪問(wèn)到另外一個(gè)加密頁(yè)的時(shí)候是否發(fā)送Referer,true為發(fā)送,false為不發(fā)送。
利用Referer防止圖片盜鏈
雖然Referer并不可靠,但用來(lái)防止圖片盜鏈還是足夠的,畢竟不是每個(gè)人都會(huì)修改客戶(hù)端的配置。實(shí)現(xiàn)一般都是通過(guò)apache的配置文件,首先設(shè)置允許訪問(wèn)的地址,標(biāo)記下來(lái):
# 只允許來(lái)自domain.com的訪問(wèn),圖片可能就放置在domain.com網(wǎng)站的頁(yè)面上
SetEnvIfNoCase Referer "^http://www.domain.com/" local_ref
# 直接通過(guò)地址訪問(wèn)
SetEnvIf Referer "^$" local_ref
然后再規(guī)定被標(biāo)記了的訪問(wèn)才被允許:
<FilesMatch ".(gif|jpg)">
Order Allow,Deny
Allow from env=local_ref
</FilesMatch>
或者
<Directory /web/images>
Order Deny,Allow
Deny from all
Allow from env=local_ref
</Directory>
這方面的文章網(wǎng)上很多,參考:
不要使用Rerferer的地方
不要把Rerferer用在身份驗(yàn)證或者其他非常重要的檢查上,因?yàn)镽erferer非常容易在客戶(hù)端被改變,不管是通過(guò)上面介紹的Firefox擴(kuò)展,或者是Privoxy,甚至是libcurl的調(diào)用,所以Rerferer數(shù)據(jù)非常之不可信。
如果你想限制用戶(hù)必須從某個(gè)入口頁(yè)面訪問(wèn)的話(huà),與其使用Referer,不如使用session,在入口頁(yè)面寫(xiě)入session,然后在其他頁(yè)面檢查,如果用戶(hù)沒(méi)有訪問(wèn)過(guò)入口頁(yè)面,那么對(duì)應(yīng)的session就不存在,參見(jiàn)這里的討論。不過(guò)和上面說(shuō)的一樣,也不要過(guò)于相信這種方式的“驗(yàn)證”結(jié)果。
個(gè)人感覺(jué)現(xiàn)在Rerferer除了用在防盜鏈,其他用途最多的就是訪問(wèn)統(tǒng)計(jì),比如統(tǒng)計(jì)用戶(hù)都是從哪里的鏈接訪問(wèn)過(guò)來(lái)的等等。
1 變量替換
public static void fun1() {
StringTemplate st = new StringTemplate(
"對(duì)象變量替換 姓名:$KeyList.Name$, 年齡:$KeyList.Age$ ");
HashMap ht = new HashMap();
ht.put("Name", "李四");
ht.put("Age", "35");
st.setAttribute("KeyList", ht);
System.out.print(st.toString());
}
2 自定義集合替換
public static void fun2() {
StringTemplate st = new StringTemplate(
"自定義集合替換 $List:{姓名:$it.Name$ 年齡:$it.Age$}$");
st.setAttribute("List.{Name,Age}", "王二", "29");
System.out.print(st.toString());
}
3 對(duì)象變量替換
定義類(lèi)
private static class User {
String name;
String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public static void fun3() {
User us = new User();
us.name = "張三";
us.age = "23";
List<User> uss = new ArrayList<User>();
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
StringTemplate st = new StringTemplate(
"<table>$Item:{<tr
class=black><td>$it.name$</td></tr>},{<tr
class=red><td>$it.age$</td></tr>};separator=\"\n\"$</table>");
st.setAttribute("Item", uss);
System.out.print(st.toString());
}
交叉替換
public static void fun4() {
User us = new User();
us.name = "張三";
us.age = "23";
List<User> uss = new ArrayList<User>();
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
uss.add(us);
StringTemplateGroup sg = new StringTemplateGroup("GroupTest");
sg.defineTemplate("RowRed",
"<tr class=red><td>$it.Name$</td><td>$it.Age$</td></tr>\n");
sg.defineTemplate("Rowblack",
"<tr class=black><td>$it.Name$</td><td>$it.Age$</td></tr>\n");
StringTemplate st = sg.defineTemplate("List",
"<table>$Item:RowRed(),Rowblack()$</table>");
st.setAttribute("Item", uss);
System.out.print(st.toString());
}
4 條件判斷
public static void fun5() {
StringTemplate st = new StringTemplate(
"當(dāng)前用戶(hù)登陸狀態(tài): $if(IsAdmin)$ 用戶(hù)登陸成功! $else$ 用戶(hù)沒(méi)有登陸! $endif$");
st.setAttribute("IsAdmin", true);
System.out.print(st.toString());
}
5 sql語(yǔ)句實(shí)現(xiàn)
theQuery.st內(nèi)容
SELECT $column; separator=","$ FROM $table$;
public static void fun6() {
// 一個(gè)sql語(yǔ)句的實(shí)現(xiàn)
StringTemplateGroup group = new StringTemplateGroup("myGroup", "c:/");
StringTemplate query = group.getInstanceOf("theQuery");
query.setAttribute("column", "name");
query.setAttribute("column", "email");
query.setAttribute("table", "User");
System.out.print(query.toString());
}
6 使用AttributeRenderer
private static class DateRenderer implements AttributeRenderer {
public String toString(Object o) {
SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd");
return f.format(((Calendar) o).getTime());
}
}
public static void fun7() {
StringTemplate st = new StringTemplate("date: <created>",
AngleBracketTemplateLexer.class);
st.setAttribute("created", new GregorianCalendar(2005, 07 - 1, 05));
st.registerRenderer(GregorianCalendar.class, new DateRenderer());
String result = st.toString();
System.out.print(result.toString());
}
在Linux上習(xí)慣了自動(dòng)補(bǔ)全功能,在Windows上還真有些不習(xí)慣,好在微軟也體諒我們大家,通過(guò)修改注冊(cè)表可以實(shí)現(xiàn)此功能。HKEY_LOCAL_MACHINE-->Software-->Microsoft-->Command Prosessor-->PathCompletionChar的鍵值改為9(16進(jìn)制)后,在Dos窗口中就可以使用自動(dòng)補(bǔ)齊功能了。
1.抽象:
抽象就是忽略一個(gè)主題中與當(dāng)前目標(biāo)無(wú)關(guān)的那些方面,以便更充分地注意與當(dāng)前目標(biāo)有關(guān)的方面。抽象并不打算了解全部問(wèn)題,而只是選擇其中的一部分,暫時(shí)不用部分細(xì)節(jié)。抽象包括兩個(gè)方面,一是過(guò)程抽象,二是數(shù)據(jù)抽象。
2.繼承:
繼
承是一種聯(lián)結(jié)類(lèi)的層次模型,并且允許和鼓勵(lì)類(lèi)的重用,它提供了一種明確表述共性的方法。對(duì)象的一個(gè)新類(lèi)可以從現(xiàn)有的類(lèi)中派生,這個(gè)過(guò)程稱(chēng)為類(lèi)繼承。新類(lèi)繼
承了原始類(lèi)的特性,新類(lèi)稱(chēng)為原始類(lèi)的派生類(lèi)(子類(lèi)),而原始類(lèi)稱(chēng)為新類(lèi)的基類(lèi)(父類(lèi))。派生類(lèi)可以從它的基類(lèi)那里繼承方法和實(shí)例變量,并且類(lèi)可以修改或增
加新的方法使之更適合特殊的需要。
3.封裝:
封裝是把過(guò)程和數(shù)據(jù)包圍起來(lái),對(duì)數(shù)據(jù)的訪問(wèn)只能通過(guò)已定義的界面。面向?qū)ο笥?jì)算始于這個(gè)基本概念,即現(xiàn)實(shí)世界可以被描繪成一系列完全自治、封裝的對(duì)象,這些對(duì)象通過(guò)一個(gè)受保護(hù)的接口訪問(wèn)其他對(duì)象。
4.多態(tài)性:
多態(tài)性是指允許不同類(lèi)的對(duì)象對(duì)同一消息作出響應(yīng)。多態(tài)性包括參數(shù)化多態(tài)性和包含多態(tài)性。多態(tài)性語(yǔ)言具有靈活、抽象、行為共享、代碼共享的優(yōu)勢(shì),很好的解決了應(yīng)用程序函數(shù)同名問(wèn)題。
Oracle數(shù)據(jù)庫(kù)由
數(shù)據(jù)文件,控制文件和聯(lián)機(jī)日志文件三種文件組成。
由于磁盤(pán)空間的變化,或者基于數(shù)據(jù)庫(kù)磁盤(pán)I/O性能的調(diào)整等,我們可能會(huì)考慮移動(dòng)數(shù)據(jù)庫(kù)文件。(
注:恢復(fù)數(shù)據(jù)庫(kù)時(shí)非常有用,屬于冷備份)
查詢(xún)當(dāng)前數(shù)據(jù)庫(kù)中,相關(guān)文件路徑
select * from v$datafile;
select * from v$controlfile;
select * from v$logfile;
根據(jù)以上路徑,找到當(dāng)前數(shù)據(jù)庫(kù)相應(yīng)文件路徑。
一.移動(dòng)數(shù)據(jù)文件:
可以用ALTER DATABASE,ALTER TABLESPACE兩種方法移動(dòng)數(shù)據(jù)文件。
1. ALTER DATABASE方法;
-- 用此方法,可以移動(dòng)任何表空間的數(shù)據(jù)文件。
STEP 1. 停數(shù)據(jù)庫(kù):
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2.用操作系統(tǒng)命令移動(dòng)數(shù)據(jù)文件:
將數(shù)據(jù)文件 'test.dbf' 從/ora/oracle/data1目錄移動(dòng)到/ora/oracle/data2目錄下:
mv /ora/oracle/data1/test.dbf /ora/oracle/data2
STEP 3. Mount數(shù)據(jù)庫(kù),用ALTER DATABASE命令將數(shù)據(jù)文件改名:
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/test.dbf' TO '/ora/oracle/data2/test.dbf';
STEP 4. 打開(kāi)數(shù)據(jù)庫(kù):.
SQL> ALTER DATABASE OPEN;
SQL>SELECT NAME,STATUS FROM V$DATAFILE;
2. ALTER TABLESPACE方法:
用此方法,要求此數(shù)據(jù)文件既不屬于SYSTEM表空間,也不屬于含有ACTIVE回滾段或臨時(shí)段的表空間。覺(jué)得麻煩,省略不用了。
二. 移動(dòng)控制文件:
控制文件 在 INIT.ORA文件中指定。移動(dòng)控制文件相對(duì)比較簡(jiǎn)單,下數(shù)據(jù)庫(kù),
編輯INIT.ORA,移動(dòng)控制文件,重啟動(dòng)數(shù)據(jù)庫(kù)。
STEP 1. 停數(shù)據(jù)庫(kù):
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2.用操作系統(tǒng)命令 移動(dòng)控制文件:
--將控制文件'ctl3orcl.ctl' 從/ora/oracle/data1目錄移動(dòng)到/ora/oracle/data2目錄下:
mv /ora/oracle/data1/ctl3orcl.ctl /ora/oracle/data2
STEP 3. 編輯INIT.ORA文件:
INIT.ORA文件的在ORACLE_HOME/dbs目錄下,
修改參數(shù) "control_files",其中指定移動(dòng)后的控制文件:
control_files = (/ora/oracle/data1/ctrlorcl1.ctl,/ora/oracle/data1/ctrlorcl2.ctl,/ora/oracle/data2/ctrlorcl3.ctl)
STEP 4. 重啟動(dòng)數(shù)據(jù)庫(kù):
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP;
SQL>SELECT name FROM V$CONTROLFILE;
SQL> EXIT;
三. 移動(dòng)聯(lián)機(jī)日志文件:
STEP 1. 停數(shù)據(jù)庫(kù):
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> SHUTDOWN;
SQL> EXIT;
STEP 2. 用操作系統(tǒng)命令移動(dòng)聯(lián)機(jī)日志文件:
--將聯(lián)機(jī)日志文件'redolog1.log' 從/ora/oracle/data1目錄移動(dòng)到/ora/oracle/data2目錄下:
mv /ora/oracle/data1/redolog1.log /ora/oracle/data2
STEP 3. Mount數(shù)據(jù)庫(kù),用ALTER DATABASE 命令改聯(lián)機(jī)日志文件名:.
sqlplus /nolog
SQL> CONNECT INTERNAL;
SQL> STARTUP MOUNT ;
SQL> ALTER DATABASE RENAME FILE '/ora/oracle/data1/redolog1.log' TO '/ora/oracle/data2/redolog1.log';
STEP 4.重啟動(dòng)數(shù)據(jù)庫(kù): .
SQL> ALTER DATABASE OPEN;
SQL>SELECT MEMBER FROM V$LOGFILE;
最近接觸Jakarta-Common-BeanUtils這個(gè)東東比較 多,于是對(duì)Apache Jakarta
Project產(chǎn)生了興趣,上他們的官方網(wǎng)站上看了下感覺(jué)有用的東西好多,眼花繚亂的,又沒(méi)有中文網(wǎng)站,又上各大論壇搜了下,也沒(méi)有發(fā)現(xiàn)一個(gè)集中該項(xiàng)目的
資料,于是決定自己整理翻譯一下,有助于各位網(wǎng)友更好的了解該項(xiàng)目。如果有什么描述不對(duì)不全面的地方,希望各位提出來(lái)給大家分享。
Jakarta項(xiàng)目是ASF(The Apache Software
Foundation)的一部分。ASF是一個(gè)非贏利組織,她鼓勵(lì)基于開(kāi)放的軟件許可下進(jìn)行合作、注重實(shí)效的開(kāi)發(fā),并提供各個(gè)領(lǐng)域的高質(zhì)量軟件,她涉及到
Http服務(wù)器,編譯工具,類(lèi)庫(kù),開(kāi)發(fā)架構(gòu),服務(wù)器端Java技術(shù),J2EE容器,數(shù)據(jù)庫(kù)工具,日志工具,XML解析等等諸多領(lǐng)域。ASF提供的java
項(xiàng)目有一部分在Jakarta中,還有一些成為獨(dú)立的諸如Tomcat的項(xiàng)目,Jakarta項(xiàng)目則提供了多種多樣開(kāi)源的java解決通用方案。
先介紹一下ASF中和Jakarta項(xiàng)目并列的java項(xiàng)目:
Ant ——java構(gòu)建工具,使用一個(gè)配置文件就可以完成java的項(xiàng)目的,編譯、打包、測(cè)試、運(yùn)行、部署、生成文檔等諸多工作。
Avalon ——是一個(gè)包括核心框架、工具、組件和容器的面向組件編程(AOP)的完整開(kāi)發(fā)平臺(tái)。使用關(guān)鍵設(shè)計(jì)模式,如反向控制模式(IoC)和分離考慮模(SoC)。 Avalon提供各種基本組件和缺省的應(yīng)用程序模塊,幫助你快速的建立你自己的應(yīng)用程序解決方案。
Excalibur ——集多個(gè)開(kāi)源項(xiàng)目(Avalon Framework、LogKit和Cornerstone)于一身的輕量級(jí)可嵌入式反向控制容器。
Gump ——是Apache組織自己也使用的一個(gè)持續(xù)集成工具,全面支持Ant和Maven,當(dāng)有新的改動(dòng)提交到版本控制系統(tǒng),它可以檢查出潛在的沖突,并及時(shí)通知項(xiàng)目組的所有成員并自動(dòng)生成改動(dòng)的詳細(xì)報(bào)告。
James ——是一套用java開(kāi)發(fā)的郵件、新聞組、消息服務(wù)器,提供了比較完善的配置方案,尤其是關(guān)于郵件內(nèi)容存儲(chǔ)和用戶(hù)信息存儲(chǔ)。 支持 SMTP, POP3 , NNTP , IMAP 。
Logging ——可靠,快速的日志工具。
Lucene
——Java開(kāi)發(fā)的高性能,全方位的文本搜索引擎。替文件的每一個(gè)字作索引,索引讓搜尋的效率比傳統(tǒng)的逐字比較大大提高,
Lucen提供一組解讀,過(guò)濾,分析文件,編排和使用索引的API,它的強(qiáng)大之處除了高效和簡(jiǎn)單外,是最重要的是使使用者可以隨時(shí)應(yīng)自已需要自訂其功能。
Maven ——是一個(gè)潛在的基于java的apache ant的構(gòu)建工具的替代者。提供了更強(qiáng)大的功能和易用性。
Portals
——提供了功能全面的、具有商業(yè)價(jià)值的企業(yè)門(mén)戶(hù)。門(mén)戶(hù)概念:門(mén)戶(hù)對(duì)企業(yè)內(nèi)的各種資源如信息管理系統(tǒng)進(jìn)行整合并通過(guò)單一接口對(duì)外提供服務(wù),雇員、合伙人及顧
客可以通過(guò)任何裝置在任何地點(diǎn)通過(guò)門(mén)戶(hù)入口享受到企業(yè)提供的服務(wù),分析家們預(yù)計(jì),門(mén)戶(hù)將成為下一代的桌面環(huán)境。
Struts ——一個(gè)實(shí)現(xiàn)MVC model2的web應(yīng)用程序開(kāi)發(fā)框架。通過(guò)一個(gè)配置文件可以很好的對(duì)各種組件進(jìn)行裝配,結(jié)構(gòu)清晰,應(yīng)用的最廣泛的額web開(kāi)發(fā)框架。
Tapestry——類(lèi)似 Struts,也是一個(gè)基于servlet的應(yīng)用程序框架,支持MVC,出現(xiàn)的較晚,不如Struts普及,主要利用javabean和xml技術(shù)進(jìn)行開(kāi)發(fā),
Tomcat ——Serlvet容器,同時(shí)具有傳統(tǒng)的Web服務(wù)器的功能,如:處理Html頁(yè)面。能夠處理動(dòng)靜態(tài)網(wǎng)頁(yè)。
Watchdog ——用來(lái)檢查一個(gè)servlet或jsp容器在相應(yīng)規(guī)范上的執(zhí)行情況的兼容性。但是該項(xiàng)目已經(jīng)靜止了,只支持Servlet2.3、JSP1.2,相應(yīng)的Serlvet容器如Tomcat也只支持Tomcat4.x。
下面介紹下Jakarta的各個(gè)子項(xiàng)目:
Alexandria——已經(jīng)不再開(kāi)發(fā)
BCEL ——The Byte Code Engineering Library
(formerly known as JavaClass) 字節(jié)碼引擎類(lèi)庫(kù),它讓用戶(hù)方便的分析,創(chuàng)建,操作java的class文件成為可能。
它可以讓您深入 JVM 匯編語(yǔ)言進(jìn)行類(lèi)操作的細(xì)節(jié)。
BSF ——bean腳本框架 在java應(yīng)用內(nèi)對(duì)腳本語(yǔ)言提供了支持,通過(guò)腳本語(yǔ)言可以訪問(wèn)java的對(duì)象和方法。
Cactus ——一個(gè)基于JUnit框架的簡(jiǎn)單測(cè)試框架,用來(lái)單元測(cè)試服務(wù)端Java代碼。 Cactus單元測(cè)試服務(wù)端內(nèi)容包括servlet,EJB, tag librarie, filter等
Commons ——提供很多日常開(kāi)發(fā)中使用率很高的功能解決方案,已被很多著名的開(kāi)源項(xiàng)目采用。具體的項(xiàng)目列表后面會(huì)有。
ECS ——使用Java語(yǔ)言和面向?qū)ο蠓椒▌?chuàng)建標(biāo)記語(yǔ)言文檔(HTML,XML)的開(kāi)源項(xiàng)目。
HiveMind ——是一個(gè)服務(wù)和配置的微型內(nèi)核, 一套通過(guò)簡(jiǎn)單的java對(duì)象和接口創(chuàng)建復(fù)雜應(yīng)用的框架。
HttpComponents ——提供了java.net包所不能提供的更多強(qiáng)大的、方便的http協(xié)議處理功能。
JCS ——一個(gè)分布式的緩存系統(tǒng),用來(lái)提高應(yīng)用程序的性能,并且提供很多強(qiáng)大的額外功能。
JMeter
——純java開(kāi)發(fā)的一套桌面應(yīng)用程序。用來(lái)進(jìn)行功能測(cè)試和性能測(cè)試。它可以用來(lái)測(cè)試靜止資料庫(kù)或者活動(dòng)資料庫(kù)中的服務(wù)器的運(yùn)行情況,可以用來(lái)模擬對(duì)服務(wù)
器或者網(wǎng)絡(luò)系統(tǒng)加以重負(fù)荷以測(cè)試它的抵抗,或者用來(lái)分析不同負(fù)荷類(lèi)型下的所有運(yùn)行情況。它也提供了一個(gè)可替換的界面用來(lái)定制數(shù)據(jù)顯示,測(cè)試同步及測(cè)試的創(chuàng)
建和執(zhí)行。
ORO ——一套文本處理工具,能提供perl5.0兼容的正則表達(dá)式、 AWK-like正則表達(dá)式, glob 表達(dá)式。還提供替換,分割,文件名過(guò)慮等功能。
POI ——一套用來(lái)創(chuàng)建,讀寫(xiě)基于OLE 2組件文檔格式的文件。使用Java來(lái)讀寫(xiě)MS Excel ,Word文件。
Regexp ——一套純java的正則表達(dá)式相關(guān)的包。
Slide ——主要模塊是一個(gè)可以做為內(nèi)容管理框架底層的內(nèi)容倉(cāng)庫(kù).它可以把內(nèi)容信息存取到專(zhuān)門(mén)的,異質(zhì)的,分布式的數(shù)據(jù)庫(kù)中.Slide還增加了security, locking, versioning等特性.
Taglibs ——一套在開(kāi)發(fā)web應(yīng)用時(shí)十分有用的,jsp 通用 tag包。
Turbine ——類(lèi)似 Struts,也是一個(gè)基于servlet的應(yīng)用程序框架,支持MVC。提供了大量可重用的組件。此框架包中包含了大量組件,但是這些組件是離散的。
Velocity
——是一個(gè)基于java的模板引擎(template engine)。它允許任何人僅僅簡(jiǎn)單的使用模板語(yǔ)言(template
language)來(lái)引用由java代碼定義的對(duì)象。
當(dāng)Velocity應(yīng)用于web開(kāi)發(fā)時(shí),界面設(shè)計(jì)人員可以和java程序開(kāi)發(fā)人員同步開(kāi)發(fā)一個(gè)遵循MVC架構(gòu)的web站點(diǎn),也就是說(shuō),頁(yè)面設(shè)計(jì)人員可以只
關(guān)注頁(yè)面的顯示效果,而由java程序開(kāi)發(fā)人員關(guān)注業(yè)務(wù)邏輯編碼。 Velocity將
java代碼從web頁(yè)面中分離出來(lái),這樣為web站點(diǎn)的長(zhǎng)期維護(hù)提供了便利, 同時(shí)也為我們?cè)贘SP和PHP之外又提供了一種可選的方案。
Velocity的能力遠(yuǎn)不止web站點(diǎn)開(kāi)發(fā)這個(gè)領(lǐng)域,例如,它可以從模板(template)產(chǎn)生SQL和PostScript、XML,它也可以被當(dāng)
作一個(gè)獨(dú)立工具來(lái)產(chǎn)生源代碼和報(bào)告,或者作為其他系統(tǒng)的集成組件使用。Velocity也可以為T(mén)urbine
web開(kāi)發(fā)架構(gòu)提供模板服務(wù)(template service)。
Velocity+Turbine提供一個(gè)模板服務(wù)的方式允許一個(gè)web應(yīng)用以一個(gè)真正的MVC模型進(jìn)行開(kāi)發(fā)。
Apache java項(xiàng)目全介紹2
下面介紹一下Jakarta下的Commons:一個(gè)csdn網(wǎng)友描述得很貼切,Commons就好比一個(gè)java百寶箱。
commons分為3部分Commons Proper、Commons Sandbox和Commons Dormant。
Commons Proper:提供了設(shè)計(jì)良好可重用的java組件,并都經(jīng)過(guò)了廣泛、嚴(yán)格的測(cè)試。
Commons Sandbox:處于實(shí)驗(yàn)、測(cè)試階段的組件。
Commons Dormant:處于停滯狀態(tài),從Sandbox退出的,不活躍的組件,謹(jǐn)慎使用。
Commons Proper組件:
Attributes—— 支持源代碼級(jí)的元數(shù)據(jù)。
BeanUtils——提供對(duì) Java 反射和自省API的包裝,處理javabean的工具。
Betwixt——將JavaBeans與XML相互轉(zhuǎn)換。
Chain——對(duì)Chain of Responsibility(責(zé)任鏈)設(shè)計(jì)模式的實(shí)現(xiàn)。使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。
CLI——處理命令行的命令的解析。
Codec——包含一些通用的編碼解碼算法。包括一些語(yǔ)音編碼器, Hex, Base64, 以及URL encoder。
Collections——擴(kuò)展和增加標(biāo)準(zhǔn)的 Java Collection框架。
Configuration——操作各種格式的配置文件。Properties文件 /XML文件 /JNDI /JDBC 數(shù)據(jù)源 /System properties /Applet parameters / Servlet parameters
Daemon——?jiǎng)?chuàng)建類(lèi)似unix守護(hù)線(xiàn)程的java代碼,可以安全地執(zhí)行一些后臺(tái)操作,線(xiàn)程不被某個(gè)應(yīng)用程序控制,而是由操作系統(tǒng)控制類(lèi)似windows的service,可以設(shè)置一個(gè)服務(wù)依賴(lài)于另一個(gè)服務(wù),一個(gè)服務(wù)關(guān)閉前必須先執(zhí)行另一個(gè)服務(wù)。
DBCP——一個(gè)數(shù)據(jù)庫(kù)連接池
DbUtils——一個(gè)JDBC的工具類(lèi),比如可以將ResultSets生成javabean。
Digester——基于規(guī)則的XML文檔解析,主要用于XML到Java對(duì)象的映射.
Discovery——提供工具來(lái)定位資源 (包括類(lèi)) ,通過(guò)使用各種模式來(lái)映射服務(wù)/引用名稱(chēng)和資源名稱(chēng)。
EL——JSP 2.0引入的表達(dá)式
Email——處理e-mail
FileUpload——web應(yīng)用中的文件上傳組件
HttpClient——使用HTTP協(xié)議的客戶(hù)端開(kāi)發(fā)框架
IO——幫助進(jìn)行IO功能開(kāi)發(fā)
Jelly
——Jelly能夠把XML轉(zhuǎn)換成可執(zhí)行代碼,所以Jelly是一個(gè)基于XML與Java的腳本和處理引擎。
Jelly借鑒了JSP定指標(biāo)簽,Velocity,
Cocoon和Xdoclet中的腳本引擎的許多優(yōu)點(diǎn)。Jelly可以用在命令行,Ant或者Servlet之中。
Jexl——Jexl是一個(gè)表達(dá)式語(yǔ)言,通過(guò)借鑒來(lái)自于Velocity的經(jīng)驗(yàn)擴(kuò)展了JSTL定義的表達(dá)式語(yǔ)言。
JXPath——使用XPath語(yǔ)法操作javabean的工具。
Lang——提供對(duì)java.lang包的擴(kuò)展。
Launcher——跨平臺(tái)的java程序的啟動(dòng)
Logging
——提供的是一個(gè)日志(Log)接口(interface),同時(shí)兼顧輕量級(jí)和不依賴(lài)于具體的日志實(shí)現(xiàn)工具。它提供給中間件/日志工具開(kāi)發(fā)者一個(gè)簡(jiǎn)單的日
志操作抽象,允許程序開(kāi)發(fā)人員使用不同的具體日志實(shí)現(xiàn)工具。用戶(hù)被假定已熟悉某種日志實(shí)現(xiàn)工具的更高級(jí)別的細(xì)節(jié)。JCL提供的接口,對(duì)其它一些日志工具,
包括Log4J, Avalon LogKit, and JDK 1.4等,進(jìn)行了簡(jiǎn)單的包裝,此接口更接近于Log4J和LogKit的實(shí)現(xiàn).
Math——Math 是一個(gè)輕量的,自包含的數(shù)學(xué)和統(tǒng)計(jì)組件,解決了許多非常通用但沒(méi)有及時(shí)出現(xiàn)在Java標(biāo)準(zhǔn)語(yǔ)言中的實(shí)踐問(wèn)題.
Modeler—— 支持兼容JMX規(guī)范的MBeans開(kāi)發(fā)。
Net——集合了網(wǎng)絡(luò)工具和協(xié)議工具的實(shí)現(xiàn)
Pool——Commons-Pool 提供了通用對(duì)象池接口,一個(gè)用于創(chuàng)建模塊化對(duì)象池的工具包,以及通常的對(duì)象池實(shí)現(xiàn)。
Primitives——對(duì)java原始類(lèi)型的支持。
SCXML——處理SCXML
Transaction——事務(wù)處理,實(shí)現(xiàn)了多層次鎖、事務(wù)集合、事務(wù)文件的訪問(wèn)。
Validator——提供了一個(gè)簡(jiǎn)單的,可擴(kuò)展的框架來(lái)在一個(gè)XML文件中定義校驗(yàn)器 (校驗(yàn)方法)和校驗(yàn)規(guī)則。支持校驗(yàn)規(guī)則的和錯(cuò)誤消息的國(guó)際化。
VFS——訪問(wèn)各種文件系統(tǒng),可以是本地文件、HTTP服務(wù)器上的文件、zip中的文件。
Commons Sandbox組件:
Compress——處理壓縮文件如tar, zip 和 bzip2 格式。
CSV——處理CSV文件
Exec——安全地處理外部進(jìn)程
Finder——實(shí)現(xiàn)類(lèi)似UNIX find命令的功能
I18n——處理軟件的I18n功能
Id——生成id號(hào)功能
Javaflow——捕捉程序運(yùn)行狀態(tài)
JCI——java編譯接口
OpenPGP——處理加密方法OpenPGP.
Pipeline——處理類(lèi)似工作隊(duì)列的管道工具
Proxy——生成動(dòng)態(tài)代理
Alias Type
Transaction manager aliases
JDBC com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig
JTA com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
EXTERNAL com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
Data types
string java.lang.String
byte java.lang.Byte
long java.lang.Long
short java.lang.Short
int java.lang.Integer
integer java.lang.Integer
double java.lang.Double
float java.lang.Float
boolean java.lang.Boolean
date java.util.Date
decimal java.math.BigDecimal
object java.lang.Object
map java.util.Map
hashmap java.util.HashMap
list java.util.List
arraylist java.util.ArrayList
collection java.util.Collection
iterator java.util.Iterator
Data source factory types
SIMPLE com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory
DBCP com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory
JNDI com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory
Cache controller types
FIFO com.ibatis.sqlmap.engine.cache.fifo.FifoCacheController
LRU com.ibatis.sqlmap.engine.cache.lru.LruCacheController
MEMORY com.ibatis.sqlmap.engine.cache.memory.MemoryCacheController
OSCACHE com.ibatis.sqlmap.engine.cache.oscache.OSCacheController
XML result types
Dom com.ibatis.sqlmap.engine.type.DomTypeMarker
domCollection com.ibatis.sqlmap.engine.type.DomCollectionTypeMarker
Xml com.ibatis.sqlmap.engine.type.XmlTypeMarker
XmlCollection com.ibatis.sqlmap.engine.type.XmlCollectionTypeMarker
事務(wù)處理是所有大型數(shù)據(jù)庫(kù)產(chǎn)品的一個(gè)關(guān)鍵問(wèn)題,各數(shù)據(jù)庫(kù)廠商都在這個(gè)方面花費(fèi)了很大精力,不同的事務(wù)處理方式會(huì)導(dǎo)致數(shù)據(jù)庫(kù)性能和功能上的巨大差異。
事務(wù)處理也是數(shù)據(jù)庫(kù)管理員與數(shù)據(jù)庫(kù)應(yīng)用程序開(kāi)發(fā)人員必須深刻理解的一個(gè)問(wèn)題,對(duì)這個(gè)問(wèn)題的疏忽可能會(huì)導(dǎo)致應(yīng)用程序邏輯錯(cuò)誤以及效率低下。
下
面我們針對(duì)Oracle及SQL
Server這兩種當(dāng)前廣泛使用的大型數(shù)據(jù)庫(kù)產(chǎn)品,探討一下它們?cè)谑聞?wù)處理方面的一些差異。如沒(méi)有特殊說(shuō)明,本文內(nèi)容適用的數(shù)據(jù)庫(kù)產(chǎn)品版本為
Oracle9i及SQL Server 2000,其中的示例SQL語(yǔ)句,對(duì)于Oracle是在SQL*Plus中執(zhí)行,而對(duì)于SQL Server
2000是在osql中執(zhí)行。
1. 事務(wù)的概念
事務(wù)可以看作是由對(duì)數(shù)據(jù)庫(kù)的若干操作組成的一個(gè)單元,這些操作要么都完成,要么都取消,從而保證數(shù)據(jù)滿(mǎn)足一致性的要求。事務(wù)的一個(gè)典型例子是銀行中的轉(zhuǎn)帳
操作,帳戶(hù)A把一定數(shù)量的款項(xiàng)轉(zhuǎn)到帳戶(hù)B上,這個(gè)操作包括兩個(gè)步驟,一個(gè)是從帳戶(hù)A上把存款減去一定數(shù)量,二是在帳戶(hù)B上把存款加上相同的數(shù)量。這兩個(gè)步
驟顯然要么都完成,要么都取消,否則銀行就會(huì)受損失。顯然,這個(gè)轉(zhuǎn)帳操作中的兩個(gè)步驟就構(gòu)成一個(gè)事務(wù).
數(shù)據(jù)庫(kù)中的事務(wù)還有如下ACID特征。
ACID分別是四個(gè)英文單詞的首寫(xiě)字母,這四個(gè)英文單詞是Atomicity、Consistency、Isolation、Durability,分別翻譯為原子性、一致性、隔離性、持久性。
原子性:指事務(wù)中的操作,或者都完成,或者都取消。
一致性:指事務(wù)中的操作保證數(shù)據(jù)庫(kù)中的數(shù)據(jù)不會(huì)出現(xiàn)邏輯上不一致的情況,一致性一般會(huì)隱含的包括在其他屬性之中。
隔離性:指當(dāng)前的事務(wù)與其他未完成的事務(wù)是隔離的。在不同的隔離級(jí)別下,事務(wù)的讀取操作,可以得到的結(jié)果是不同的。
持久性:指對(duì)事務(wù)發(fā)出COMMIT命令后,即使這時(shí)發(fā)生系統(tǒng)故障,事務(wù)的效果也被持久化了。與此相反的是,當(dāng)在事務(wù)執(zhí)行過(guò)程中,系統(tǒng)發(fā)生故障,則事務(wù)的操作都被回滾,即數(shù)據(jù)庫(kù)回到事務(wù)開(kāi)始之前的狀態(tài)。
對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)修改都是在內(nèi)存中完成的,這些修改的結(jié)果可能已經(jīng)寫(xiě)到硬盤(pán)也可能沒(méi)有寫(xiě)到硬盤(pán),如果在操作過(guò)程中,發(fā)生斷電或系統(tǒng)錯(cuò)誤等故障,數(shù)據(jù)庫(kù)可以
保證未結(jié)束的事務(wù)對(duì)數(shù)據(jù)庫(kù)的數(shù)據(jù)修改結(jié)果即使已經(jīng)寫(xiě)入磁盤(pán),在下次數(shù)據(jù)庫(kù)啟動(dòng)后也會(huì)被全部撤銷(xiāo);而對(duì)于結(jié)束的事務(wù),即使其修改的結(jié)果還未寫(xiě)入磁盤(pán),在數(shù)據(jù)
庫(kù)下次啟動(dòng)后會(huì)通過(guò)事務(wù)日志中的記錄進(jìn)行“重做”,即把丟失的數(shù)據(jù)修改結(jié)果重新生成,并寫(xiě)入磁盤(pán),從而保證結(jié)束事務(wù)對(duì)數(shù)據(jù)修改的永久化。這樣也保證了事務(wù)
中的操作要么全部完成,要么全部撤銷(xiāo)。
2. 事務(wù)設(shè)置及類(lèi)型的區(qū)別
在SQL Server中有三種事務(wù)類(lèi)型,分別是:隱式事務(wù)、顯式事務(wù)、自動(dòng)提交事務(wù),缺省為自動(dòng)提交。
自動(dòng)提交,是指對(duì)于用戶(hù)發(fā)出的每條SQL語(yǔ)句,SQL Server都會(huì)自動(dòng)開(kāi)始一個(gè)事務(wù),并且在執(zhí)行后自動(dòng)進(jìn)行提交操作來(lái)完成這個(gè)事務(wù),也可以說(shuō)在這種事務(wù)模式下,一個(gè)SQL語(yǔ)句就是一個(gè)事務(wù)。
顯式事務(wù),是指在自動(dòng)提交模式下以Begin
Transaction開(kāi)始一個(gè)事務(wù),以Commit或Rollback結(jié)束一個(gè)事務(wù),以Commit結(jié)束事務(wù)是把事務(wù)中的修改永久化,即使這時(shí)發(fā)生斷電
這樣的故障。例如下面是SQL Server中的一個(gè)顯式事務(wù)的例子。
Begin Tran
Update emp Set ename=’Smith’ Where empno=7369
Insert Into dept Values(60,’HR’,’GZh’)
Commit
<!--[if !vml]--><!--[endif]-->
隱式事務(wù),是指在當(dāng)前會(huì)話(huà)中用Set Implicit_Transactions On命令設(shè)置的事務(wù)類(lèi)型,這時(shí)任何DML語(yǔ)句(Delete、Update、Insert)都會(huì)開(kāi)始一個(gè)事務(wù),而事務(wù)的結(jié)束也是用Commit或Rollback。
在Oracle中沒(méi)有SQL Server的這些事務(wù)類(lèi)型,缺省情況下任何一個(gè)DML語(yǔ)句都會(huì)開(kāi)始一個(gè)事務(wù),直到用戶(hù)發(fā)出Commit或Rollback操作,這個(gè)事務(wù)才會(huì)結(jié)束,這與SQL Server的隱式事務(wù)模式相似。
3. 事務(wù)隔離級(jí)別
在SQL92標(biāo)準(zhǔn)中,事務(wù)隔離級(jí)別分為四種,分別為:Read Uncommitted、Read
Committed、Read Repeatable、Serializable,其中Read Uncommitted與Read
Committed為語(yǔ)句級(jí)別的,而Read Repeatable與Serializable是針對(duì)事務(wù)級(jí)別的。
在Oracle和SQL Server中設(shè)置事務(wù)隔離級(jí)別的語(yǔ)句是相同的,都使用SQL92標(biāo)準(zhǔn)語(yǔ)法,即:
Set Transaction Isolation Level Read Committed
上面示例中的Read Committed可以被替換為其他三種隔離級(jí)別中的任意一種。
1) SQL Server中的隔離級(jí)別及實(shí)現(xiàn)機(jī)制
在SQL Server中提供了所有這四種隔離級(jí)別。
下面我們討論在SQL Server中,這幾種隔離級(jí)別的含義及其實(shí)現(xiàn)方式。
Read Uncommitted:一個(gè)會(huì)話(huà)可以讀取其他事務(wù)未提交的更新結(jié)果,如果這個(gè)事務(wù)最后以回滾結(jié)束,這時(shí)的讀取結(jié)果就可能是錯(cuò)誤的,所以多數(shù)的數(shù)據(jù)庫(kù)應(yīng)用都不會(huì)使用這種隔離級(jí)別。
Read Committed:這是SQL
Server的缺省隔離級(jí)別,設(shè)置為這種隔離級(jí)別的事務(wù)只能讀取其他事務(wù)已經(jīng)提交的更新結(jié)果,否則,發(fā)生等待,但是其他會(huì)話(huà)可以修改這個(gè)事務(wù)中被讀取的記
錄,而不必等待事務(wù)結(jié)束,顯然,在這種隔離級(jí)別下,一個(gè)事務(wù)中的兩個(gè)相同的讀取操作,其結(jié)果可能不同。
Read
Repeatable:在一個(gè)事務(wù)中,如果在兩次相同條件的讀取操作之間沒(méi)有添加記錄的操作,也沒(méi)有其他更新操作導(dǎo)致在這個(gè)查詢(xún)條件下記錄數(shù)增多,則兩次
讀取結(jié)果相同。換句話(huà)說(shuō),就是在一個(gè)事務(wù)中第一次讀取的記錄保證不會(huì)在這個(gè)事務(wù)期間發(fā)生改變。SQL
Server是通過(guò)在整個(gè)事務(wù)期間給讀取的記錄加鎖實(shí)現(xiàn)這種隔離級(jí)別的,這樣,在這個(gè)事務(wù)結(jié)束前,其他會(huì)話(huà)不能修改事務(wù)中讀取的記錄,而只能等待事務(wù)結(jié)
束,但是SQL Server不會(huì)阻礙其他會(huì)話(huà)向表中添加記錄,也不阻礙其他會(huì)話(huà)修改其他記錄。
Serializable:在一個(gè)事務(wù)中,讀取操作的結(jié)果是在這個(gè)事務(wù)開(kāi)始之前其他事務(wù)就已經(jīng)提交的記錄,SQL
Server通過(guò)在整個(gè)事務(wù)期間給表加鎖實(shí)現(xiàn)這種隔離級(jí)別。在這種隔離級(jí)別下,對(duì)這個(gè)表的所有DML操作都是不允許的,即要等待事務(wù)結(jié)束,這樣就保證了在
一個(gè)事務(wù)中的兩次讀取操作的結(jié)果肯定是相同的。
2) Oracle中的隔離級(jí)別及實(shí)現(xiàn)機(jī)制
在Oracle中,沒(méi)有Read Uncommitted及Repeatable
Read隔離級(jí)別,這樣在Oracle中不允許一個(gè)會(huì)話(huà)讀取其他事務(wù)未提交的數(shù)據(jù)修改結(jié)果,從而避免了由于事務(wù)回滾發(fā)生的讀取錯(cuò)誤。Oracle中的
Read Committed和Serializable級(jí)別,其含義與SQL Server類(lèi)似,但是實(shí)現(xiàn)方式卻大不一樣。
在Oracle中,存在所謂的回滾段(Oracle9i之前版本)或撤銷(xiāo)段(Oracle9i版本),Oracle在修改數(shù)據(jù)記錄時(shí),會(huì)把這些記錄被修改
之前的結(jié)果存入回滾段或撤銷(xiāo)段中,就是因?yàn)檫@種機(jī)制,Oracle對(duì)于事務(wù)隔離級(jí)別的實(shí)現(xiàn)與SQL
Server截然不同。在Oracle中,讀取操作不會(huì)阻礙更新操作,更新操作也不會(huì)阻礙讀取操作,這樣在Oracle中的各種隔離級(jí)別下,讀取操作都不
會(huì)等待更新事務(wù)結(jié)束,更新操作也不會(huì)因?yàn)榱硪粋€(gè)事務(wù)中的讀取操作而發(fā)生等待,這也是Oracle事務(wù)處理的一個(gè)優(yōu)勢(shì)所在。
Oracle缺省的設(shè)置是Read
Committed隔離級(jí)別(也稱(chēng)為語(yǔ)句級(jí)別的隔離),在這種隔離級(jí)別下,如果一個(gè)事務(wù)正在對(duì)某個(gè)表進(jìn)行DML操作,而這時(shí)另外一個(gè)會(huì)話(huà)對(duì)這個(gè)表的記錄進(jìn)
行讀取操作,則Oracle會(huì)去讀取回滾段或撤銷(xiāo)段中存放的更新之前的記錄,而不會(huì)象SQL Server一樣等待更新事務(wù)的結(jié)束。
在Serializable隔離級(jí)別(也稱(chēng)為事務(wù)級(jí)別的隔離),事務(wù)中的讀取操作只能讀取這個(gè)事務(wù)開(kāi)始之前已經(jīng)提交的數(shù)據(jù)結(jié)果。
如果在讀取時(shí),其他事務(wù)正 在對(duì)記錄進(jìn)行修改,則Oracle就會(huì)在回滾段或撤銷(xiāo)段中去尋找對(duì)應(yīng)的原來(lái)未經(jīng)更改的記錄(而且是在讀取操作所在的事務(wù)開(kāi)始之前存放于回滾段或撤銷(xiāo)段的記 錄),這時(shí)讀取操作也不會(huì)因?yàn)橄鄳?yīng)記錄被更新而等待。
4. DDL語(yǔ)句對(duì)事務(wù)的影響
1) Oracle中DDL語(yǔ)句對(duì)事務(wù)的影響
在Oracle中,執(zhí)行DDL語(yǔ)句(如Create Table、Create View等)時(shí),會(huì)在執(zhí)行之前自動(dòng)發(fā)出一個(gè)Commit命令,并在隨后發(fā)出一個(gè)Commit或者Rollback命令,也就是說(shuō),DDL會(huì)象如下偽碼一樣執(zhí)行:
Commit;
DDL_Statement;
If (Error) then
Rollback;
Else
Commit;
End if;
我們通過(guò)分析下面例子來(lái)看Oracle中,DDL語(yǔ)句對(duì)事務(wù)的影響:
<!--[if !vml]--><!--[endif]-->Insert into some_table values(‘Before’);
<!--[if !vml]--><!--[endif]-->Creaate table T(x int);
<!--[if !vml]--><!--[endif]-->Insert into some_table values(‘After’);
<!--[if !vml]--><!--[endif]-->Rollback;
由于在Oracle執(zhí)行Create table語(yǔ)句之前進(jìn)行了提交,而在Create
table執(zhí)行后也會(huì)自動(dòng)發(fā)出Commit命令,所以只有插入After的行被回滾,而插入Before的行不會(huì)被回滾,Create
table命令的結(jié)果也不會(huì)被回滾,即使Create
table語(yǔ)句失敗,所進(jìn)行的Before插入也會(huì)被提交。如果最后發(fā)出Commit命令,因?yàn)椴迦隑efore及Create
table的操作結(jié)果已經(jīng)在之前提交,所以Commit命令影響的只有插入After的操作。
2) SQL Server中DDL語(yǔ)句對(duì)事務(wù)的影響
在SQL Server中,DDL語(yǔ)句對(duì)事務(wù)的影響與其他DML語(yǔ)句相同,也就是說(shuō),在DML語(yǔ)句發(fā)出之前或之后,都不會(huì)自動(dòng)發(fā)出Commit命令。
在SQL Server 2000中,對(duì)于與上面Oracle同樣的例子,最后發(fā)出Rollback后,數(shù)據(jù)庫(kù)會(huì)回滾到插入Before之前的狀態(tài),即插入Before和After的行都會(huì)被回滾,數(shù)據(jù)表T也不會(huì)被創(chuàng)建。
如果最后發(fā)出Commit操作,則會(huì)把三個(gè)操作的結(jié)果全部提交。
5. 用戶(hù)斷開(kāi)數(shù)據(jù)庫(kù)連接對(duì)事務(wù)的影響
另外,對(duì)應(yīng)于Oracle的管理客戶(hù)端工具SQL*Plus,在SQL Server
2000中是osql,兩種管理工具都是命令行工具,使用方式及作用也類(lèi)似,但是在SQL*Plus中,用戶(hù)退出連接時(shí),會(huì)自動(dòng)先發(fā)出Commit命令,
然后再退出,而在osql中,如果用戶(hù)退出連接,會(huì)自動(dòng)發(fā)出Rollback命令,這對(duì)于SQL
Server的自動(dòng)提交模式?jīng)]有什么影響,但如果處于隱式事務(wù)模式,其影響是顯而易見(jiàn)的。對(duì)于兩種數(shù)據(jù)庫(kù)產(chǎn)品的其他客戶(hù)端管理工具也有類(lèi)似的不同之處。
SAX (Simple API for XML) 和 DOM (Document Object Model) 是當(dāng)前兩個(gè)主要的XML API,幾乎所有商用的xml 解析器都同時(shí)實(shí)現(xiàn)了這兩個(gè)接口。因此如果你的程序使用了SAX或者DOM APIs,那么你的程序?qū)?/span>xml解析器是透明。
1. DOM以一個(gè)分層的對(duì)象模型來(lái)映射xml文檔。而SAX將文檔中的元素轉(zhuǎn)化為對(duì)象來(lái)處理。
2. DOM將文檔載入到內(nèi)存中處理,而SAX則相反,它可以檢測(cè)一個(gè)即將到來(lái)的 XML流,由此并不需要所有的XML代碼同時(shí)載入到內(nèi)存中。
SAX 處理是如何工作的
SAX 在讀取 XML 流的同時(shí)處理它們,這很像以前的自動(dòng)收?qǐng)?bào)機(jī)紙帶(ticker tape)。請(qǐng)考慮下面的 XML 代碼片斷:
<?xml version="1.0"?>
<samples>
<server>UNIX</server>
<monitor>color</monitor>
</samples>
分析這個(gè)代碼片斷的 SAX 處理器一般情況下將產(chǎn)生以下事件:
Start document
Start element (samples)
Characters (white space)
Start element (server)
Characters (UNIX)
End element (server)
Characters (white space)
Start element (monitor)
Characters (color)
End element (monitor)
Characters (white space)
End element (samples)
SAX API 允許開(kāi)發(fā)人員捕捉這些事件并對(duì)它們作出反應(yīng)。
SAX 處理涉及以下步驟:
1.
創(chuàng)建一個(gè)事件處理程序。
2.創(chuàng)建 SAX 解析器。
3.向解析器分配事件處理程序。
4.解析文檔,同時(shí)向事件處理程序發(fā)送每個(gè)事件。
基于事件的處理的優(yōu)點(diǎn)和缺點(diǎn)
這種處理的優(yōu)點(diǎn)非常類(lèi)似于流媒體的優(yōu)點(diǎn)。分析能夠立即開(kāi)始,而不是等待所有的數(shù)據(jù)被處理。而且,由于應(yīng)用程序只是在讀取數(shù)據(jù)時(shí)檢查數(shù)據(jù),
因此不需 要將數(shù)據(jù)存儲(chǔ)在內(nèi)存中。這對(duì)于大型文檔來(lái)說(shuō)是個(gè)巨大的優(yōu)點(diǎn)。事實(shí)上,應(yīng)用程序甚至不必解析整個(gè)文檔;它可以在某個(gè)條件得到滿(mǎn)足時(shí)
停止解析。一般來(lái)說(shuō),SAX 還比它的替代者 DOM 快許多。
另一方面,由于應(yīng)用程序沒(méi)有以任何方式存儲(chǔ)數(shù)據(jù),使用 SAX 來(lái)更改數(shù)據(jù)或在數(shù)據(jù)流中往后移是不可能的。
DOM 和基于樹(shù)的處理
DOM 是處理 XML 數(shù)據(jù)的傳統(tǒng)方法。使用 DOM 時(shí),數(shù)據(jù)以樹(shù)狀結(jié)構(gòu)的形式被加載到內(nèi)存中。
例如,在“SAX 處理是如何工作的”中用作例子的相同文檔在 DOM 中將表示為節(jié)點(diǎn),DOM 使用父子關(guān)系。
基于樹(shù)的處理的優(yōu)點(diǎn)和缺點(diǎn)
DOM
以及廣義的基于樹(shù)的處理具有幾個(gè)優(yōu)點(diǎn)。首先,由于樹(shù)在內(nèi)存中是持久的,因此可以修改它以便應(yīng)用程序能對(duì)數(shù)據(jù)和結(jié)構(gòu)作出更改。
它還可以在任何時(shí)候在樹(shù)中上下導(dǎo)航,而不是像 SAX 那樣是一次性的處理。DOM 使用起來(lái)也要簡(jiǎn)單得多。
另一方面,在內(nèi)存中構(gòu)造這樣的樹(shù)涉及大量的開(kāi)銷(xiāo)。大型文件完全占用系統(tǒng)內(nèi)存容量的情況并不鮮見(jiàn)。此外,創(chuàng)建一棵 DOM 樹(shù)可能是一個(gè)緩慢的過(guò)程。
如何在 SAX 和 DOM 之間選擇
選擇 DOM 還是選擇 SAX,這取決于下面幾個(gè)因素:
1.應(yīng)用程序的目的:如果打算對(duì)數(shù)據(jù)作出更改并將它輸出為 XML,那么在大多數(shù)情況下,DOM 是適當(dāng)?shù)倪x擇。并不是說(shuō)使用 SAX 就不能更改數(shù)據(jù),
但是該過(guò)程要復(fù)雜得多,因?yàn)槟仨殞?duì)數(shù)據(jù)的一份拷貝而不是對(duì)數(shù)據(jù)本身作出更改。
2.數(shù)據(jù)容量: 對(duì)于大型文件,SAX 是更好的選擇。
數(shù)據(jù)將如何使用:如果只有數(shù)據(jù)中的少量部分會(huì)被使用,那么使用 SAX 來(lái)將該部分?jǐn)?shù)據(jù)提取到應(yīng)用程序中可能更好。 另一方面,
如果您知道自己以后會(huì)回頭引用已處理過(guò)的大量信息,那么 SAX 也許不是恰當(dāng)?shù)倪x擇。
3.對(duì)速度的需要: SAX 實(shí)現(xiàn)通常要比 DOM 實(shí)現(xiàn)更快。
SAX 和 DOM 不是相互排斥的,記住這點(diǎn)很重要。您可以使用 DOM 來(lái)創(chuàng)建 SAX 事件流,也可以使用 SAX 來(lái)創(chuàng)建 DOM 樹(shù)。事實(shí)上,用于創(chuàng)建 DOM 樹(shù)的大多數(shù)解析器實(shí)際上都使用 SAX 來(lái)完成這個(gè)任務(wù)!
1、增加攔截器
<interceptor-ref name="execAndWait">
<!--等待時(shí)間,執(zhí)行時(shí)間沒(méi)有超過(guò)此值,將不顯示等待畫(huà)面(毫秒)-->
<param name="delay">1000</param>
<!-- 間隔檢查時(shí)間,檢查后臺(tái)進(jìn)程有沒(méi)有執(zhí)行完畢,如果完成了它就立刻返回-->
<param name="delaySleepInterval">50</param>
</interceptor-ref>
此攔截器必須放在所有攔截器的最后。
2、增加result
<result name="wait">wait.jsp</result>
如果沒(méi)有找到"wait"結(jié)果,struts2會(huì)自動(dòng)生成一個(gè)wait結(jié)果(\org\apache\struts2\interceptor
\wait.ftl).這個(gè)結(jié)果是用FreeMarker做的,所以需要Freemarker支持才能正常工作。如果你不想在程序中加入
FreeMarker,那就必須自己實(shí)現(xiàn)一個(gè)wait結(jié)果。這一般來(lái)說(shuō)是有必要的,因?yàn)槟J(rèn)的wait頁(yè)面很簡(jiǎn)單。
3、Action實(shí)現(xiàn)SessionAware接口
因?yàn)檫@個(gè)action將會(huì)以單獨(dú)的線(xiàn)程執(zhí)行,所以你不能用ActionContext,因?yàn)樗荰hreadLocal.這也就是說(shuō)如果你要訪問(wèn)
session數(shù)據(jù),你必須實(shí)現(xiàn) SessionAware結(jié)構(gòu)而不是調(diào)用ActionContext.getSesion() 。
public interface SessionAware{
public void setSession(Map map);
}
public abstract class AbsBasicAction extends ActionSupport implements SessionAware{
/** 當(dāng)前 Session */
protected Map session ;
public void setSession(Map session) {
this.session = session ;
}
}
4、實(shí)現(xiàn) wait 結(jié)果 映射的 wait.jsp
必須設(shè)置該頁(yè)面的meta信息,每隔5秒,重新請(qǐng)求一次前面的action。
<meta http-equiv="refresh" content="2;url=<s:url includeParams="all" />" />