版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、jdbc事務(wù)管理及savcpoint示例-編程 開發(fā)技術(shù)jdbc事務(wù)管理及savepoint示例木文由importnew劉博翻譯自journaldevo歡迎加入翻譯小組。轉(zhuǎn)載請見文末要求。在jdbc教程中,我們學(xué)習(xí)了如何使用jdbc apt進(jìn)行數(shù)據(jù)庫連接和執(zhí)行sql查詢。 此外,還研究了不同類型的驅(qū)動程序,以及如何編寫松散耦合的jdbc程序,幫 助我們輕松地切換數(shù)據(jù)庫服務(wù)器。木教程旨在詳細(xì)介紹jdbc事務(wù)管理,以及如何使用jdbc savepoint進(jìn)行冋滾操 作。默認(rèn)情況下,當(dāng)我們創(chuàng)建一個數(shù)據(jù)庫連接時,會運行在自動提交模式(auto-commit) «這意味著,任何時候我們執(zhí)行一條
2、sql完成z后,事務(wù)都 會自動捉交。所以我們執(zhí)行的每一條sql都是一個事務(wù),并且如果正在運行dml 或者ddl語句,這些改變會在每一條sql語句結(jié)束的時存入數(shù)據(jù)庫。有時候我們 想讓一組sql語句成為事務(wù)的一部分,那樣我們就可以在所有語句運行成功的吋 候提交,并11如果岀現(xiàn)任何異常,這些語句作為事務(wù)的一部分,我們可以選擇將 其全部回滾。讓我們通過一個簡單的示例理解一下,這里使用jdbc的事務(wù)管理來支持?jǐn)?shù)據(jù)的 完整性。假設(shè)我們有一個名為userdb的數(shù)據(jù)庫,員工的信息分別存儲在兩張表 屮。比如我正在使用mysql數(shù)據(jù)庫,但是同樣可以在oracle和postgresql等其 他的關(guān)系型數(shù)據(jù)庫上運行。
3、數(shù)據(jù)庫表屮存儲員工信息和地址明細(xì)。兩張表的ddl腳本如下:create table 'employee' (empld int(11) unsigned not null,'name' varchar(20) default null,primary key ('empld')engine=innodb default cilarset=utf8;create table 'address' ('empld' int(11) unsigned not null, 'address' varchar
4、(20) default null, city varchar(5) default null,'country' varchar (20) default null, primary key ('empld')engine二innodb default charset二utf8;最終的工程如下圖,我們將逐個查看這些類:如圖所示,在工程的bu訂d path h1有一個mysql jdbc的jar包,這樣就可以 連接到mysql數(shù)據(jù)庫。dbconnection. javapackage com.journaldev. jdbc. transaction;impor
5、t java. sql. connection;import java.sql.drivermanager;import java.sql.sqlexception;public class dbconnection public final static string db_driver_class =z,com. mysql. jdbc. driver;public final static string dburl =,z jdbc: mysql: /localhost: 3306/userdb; publ ic final static string db username 二 pan
6、kaj; public final static string db_password = pemkeijl23"public static connection getconnectiono throwsclassnotfoundexception,sqlexception conncction con 二 null;/ load the driver classclass.forname(db_driver_class);/ create the connection nowcon 二 drivermanager. getconnection(db url, db usernam
7、e, db_password);system, out. println(z/db connection created successfully'7); return con;在dbconnection類小,創(chuàng)建mysql數(shù)據(jù)庫連接供其他類使用。employeejdbcinsertexample. javapackage com. journaldev. jdbc. transaction;import java. sql. cormection;import java.sql.prcparcdstatcmcnt;import java.sql. sqlexception;publi
8、c class employeejdbcinsertexample public static final string insert_employee_query 二"insert into employee (empld, name) values (?,?);public static final string insert address query = "insert into address (empld, address, city, country) values (?, ?, ?, ?) ;public static void main(string ar
9、gs) cormection con 二 null;try con = dbconnection. getconnectiono ; insertemployeedata(con, 1, "pankaj); insertaddressdata(con, 1, "albany drz,, z,san jose",;catch (sqlexception | classnotfoundexccption e) e. printstacktrace ();finally try if (con != null)con. close ();catch (sqlexcept
10、ion e) e. printstacktrace ();public static void insertaddressdata(cormection con, int id,string address,string city,string country) throws sqlexception prcparcdstatcment stmt =con.preparestatement(lnsert_address_query);stmt, setlnt (1, id);stmt. setstring(2, address); stmt. setstring(3, city); stmt.
11、 setstring(4, country); stmt. executeupdate ();system, out. printin("address data inserted successfully for id二 + id);stmt, close ();publ ic static void insertemployeedata(connection con, int id, string name)throws sqlexception preparedstatement stmt 二con.preparestatement (insert employee query
12、);stmt. settnt (1, id);stmt. sctstring(2, namc);stmt. executeupdate ();system.out. printin("employee data inserted successfully forid二 + id);stmt. close();這是一個簡單的jdbc程序,向前面創(chuàng)建的employee表和address表中插入用戶 提供的數(shù)據(jù)。當(dāng)我們將運行這個程序時,將得到以下輸出:employee data inserted successful 1y for td二1com. mysql. jdbe. mysqlda
13、tatruncation: data truncation: data too long for column 'city' at row 1at com mysql. jdbe. mysqllo. checkerrorpacket (mysql10. java:2939) at com. mysql. jdbe. mysqllo. sendcommand(mysql10. java:1623) at com. mysql. jdbe. mysqlto. sqlquerydirect (mysqlto. java:1715) at com. mysql. jdbe. cormc
14、ction. cxccsql(connection. java:3249) atcom. mysql. jdbe. preparedstatement. executelnternal (preparedstatement.ja va:1268)atcom. mysql. jdbe. prcparcdstatcment. executeupdate(prcparcdstatcment. java :1541)atcom. mysql. jdbe. preparedstatement. executeupdate(preparedstatement. java :1455)atcom. mysq
15、l. jdbc. preparedstatement. executeupdate (preparedstatement.java :1440)atcom. journaldcv. jdbc. transaction. employccjdbcinscrtexeimplc. inscrtaddrc ssdata (employeejdbclnsertexample. java:45)atcom. journaldev. jdbc. transaction. employeejdbclnsertexample. main (employ eejdbcinsertexample. java:23)
16、從結(jié)果可以看到,在我們試圖往address表中插入數(shù)據(jù)時,由于輸入的值超過了 字段的大小,因此拋出了 sqlexception異常。如果瀏覽employee和address表的內(nèi)容,你會發(fā)現(xiàn)employee表冇數(shù)據(jù),address 表卻沒有。這是一個嚴(yán)重的問題,因為只有部分?jǐn)?shù)據(jù)正確地被插入。并且如果我 們再次運行這個程序,它會再次試圖向employee «插入數(shù)據(jù),并且引發(fā)下面的 異常:com. mysql. jdbc. exccptions. mysqlintcgrityconstreiiritvioldtionexccption: duplicate entry '1
17、39; for key 'primary'at com. mysql. jdbc. sqlerror. createsqlexception(sqlerror.java:931) at com. mysql. jdbc. mysqllo. checkerrorpacket(mysql10. java:2941) at com. mysql. jdbc. mysqllo. sendcommand(mysql10. java:1623) eit com. mysql. jdbc. mysqllo. sqlquerydirect(mysqllo. java: 1715) at com
18、. mysql. jdbc. connection. execsql(connection. java:3249) atcom. mysql. jdbc. preparedstatement. executelnternal(preparedstatement. ja va:1268)atcom. mysql. jdbc. preparedstatement. executeupdate (preparedstatement.java :1541)atcom. mysql. jdbc. preparedstatement. executeupdate(preparedstatement. ja
19、va :1455)atcom. mysql. jdbc. preparedstatement. executeupdate(preparedstatement.java :1440)atcom. jour neildcv. jdbc. train sac tion. employccjdbc in scr texaniplc. in scr templo yeedata(employeejdbclnsertexample. java:57)atcom. journaldev. jdbc. transaction. employeejdbclnsertexample. main(employ e
20、ejdbctusertexample. java:21)所以,我們沒冇辦法把employee對應(yīng)的address數(shù)據(jù)保存到address表屮。這 個程序造成了數(shù)據(jù)完整性的問題,這也是為什么需要用事務(wù)管理來確保兩張表都 得以成功插入,并且如果發(fā)生任何異常全部回滾。jdbc事務(wù)管理jdbc api提供了 sctautocommito方法,通過它我們可以禁用門動提交數(shù)據(jù)庫連 接。自動捉交應(yīng)該被禁用,因為只冇這樣事務(wù)才不會自動捉交,除非調(diào)用了連接 的commit ()方法。數(shù)據(jù)庫服務(wù)器使用表鎖來實現(xiàn)事務(wù)管理,并口它是一種緊張 的資源。因此,在操作完成后應(yīng)該盡快提交事務(wù)。讓我們編寫另外一個程序,這 里我
21、將使用jdbc事務(wù)管理特性來保證數(shù)據(jù)的完整性不被破壞。employeejdbctransactionexample. javapackage com. journaldev. jdbc. transaction;import java. sql. connection;import java. sql. sqlexception;public class emp 1 o)ee j dbct ran sac t i onexamp 1 e public static void main(string args) cormection con 二 null;try con = dbconnecti
22、on. getconnectiono ;/ set auto commit to falsecon. setautocommi t(false);employeejdbcinsertexample. insertemployeedata(con, 1, ,pankaj,z);employeejdbcinsertexample. insertaddressdata(con,1,"albany dr", "san jose", usa);/ now commit transactioncon. comm it ();catch (sqlexception e
23、) e. printstacktracco ;try con. rollback();system, out. printin(z/jdbc transaction rolled backsuccessfully");catch (sqlexception el) system, out. printin(,zsqlexception in rollback" +e. getmessage ();catch (classnotfoundexception e) e. printstacktrace ();finally try if (con != null)con. cl
24、ose ();catch (sqlexception e) e. pri ntstacktrace ();在運行程序之前,請確保你清楚地了解之前插入的數(shù)據(jù)。當(dāng)你運行這個程序時, 將得到下面的輸出:db connection created successfullyemployee data inserted successfully for id=1com.mysql. jdbc. mysqldatatruncation: data trimcation: data too long for column 'city' at row 1at com. mysql. jdbc.
25、mysql10. checkerrorpacket(mysql10. java:2939) at com. mysql. jdbc. mysqllo. sendcominand(mysql 10. java: 1623) at com. mysql. jdbc. mysqllo. sqlquerydirect(mysqllo. java:1715) at com. mysql. jdbc. connection. execsql(connection. java:3249) atcom. mysq1. jdbc preparedstatement executelnternal (prepar
26、edstatement ja va:1268)atcom. mysql. jdbc. preparedstatement. executeupdate(preparedstatement. java :1541)atcom. mysql. jdbc. preparedstatement. executeupdate(preparedstatement.java :1455)atcom. mysq1. jdbc prcparcdstatcment. cxccutcupdate(prcparcdstatcment.java :1440)atcom. journaldev. jdbc. transa
27、ction. employeejdbcinsertexample. insertaddre ssdata(employeejdbcinsertexample. java:45)atcom. jour naldcv. jdbc. tran sacti on. employccjdbctra nseicti on example. meiin(e mployeejdbctransactionexample. java:19)jdbc transaction rolled back successfully這段輸出和前面的程序很像,但是如果你查看數(shù)據(jù)庫衣,就會發(fā)現(xiàn)數(shù)據(jù)沒有被插 入employee表。
28、現(xiàn)在我們叮以修改城市(city)的值,這樣它就叮以符合字段 要求,重新運彳亍程序就能夠把數(shù)據(jù)插到兩張表屮。注意:只有當(dāng)兩個插入操作都 執(zhí)行成功時,連接才會提交。如果其中任何一個拋岀異常,整個事務(wù)會回滾。jdbc savepoint 示例冇時候一個事務(wù)口j能是一組復(fù)雜的語句,因此可能想要回滾到事務(wù)中某個特殊的 點。jdbc savepoint幫我們在事務(wù)中創(chuàng)建檢查點(checkpoint),這樣就可以 回滾到指定點。當(dāng)事務(wù)捉交或者整個事務(wù)回滾后,為事務(wù)產(chǎn)生的任何保存點都會 自動釋放并變?yōu)闊o效。把事務(wù)冋滾到一個保存點,會使其他所有保存點自動釋放 并變?yōu)闊o效。假設(shè)我們有一張志表logs,用來記錄員工
29、信息保存成功的志。但是因為它 只用于日志記錄,當(dāng)插入日志表有任何異常時,我們不希望回滾整個事務(wù)。我們 來看一下如何用jdbc savepoint來實現(xiàn)。create table 'logs' ('id' int(3) unsigned not null auto_increment,'message' varchar (10) default null,primary key ('id')englne=lnnodb default charset=utf8;employeejdbcsavepointexample javapack
30、age com. journaldev. jdbc iransaclion;import java sql. conncction;import java.sql.preparedstatement;import java sql. sqlexception;import java. sql. savepoint;public class emp1oyeejdbcsavepointexamp1e public static final string insertlogsquery = "insert into logs (message) values (?) ;public sta
31、tic void meiin( str in g args) connection con = null;savepoint savepoint = null;try con = dbconnection. getconnection();/ set auto commit to falsecon.setautocommit(false);employeejdbcinsertexample. insertemployeedata(con, 2,pankaj);employeejdbctnsertexomple. i nsertaddressdata(con,2, "albany dr
32、, sfo,usa);/ if code reached here, means main work is done successfully savepoint 二 con.setsavepoint("employeesavepoint); inscrtlogdata(con, 2);/ now commit transactioncon. commit (); catch (sqlexception e) e. printstacktrace ();try if (savepoint 二二 null) / sqlexception occurred in saving into
33、employee or address/ tablescon. rollback();system.out. println(jdbc transaction rolled back successfully"); else / cxccp tion occurred in inset ting into logs t able / we can ignore it by rollback to the savepoint con. rollback(savepoint);/ lets commit nowcon. commi t ();catch (sqlexception el)
34、 system, out printin("sqlexception in rollback" +e. getmessage ();catch (classnotfoundexccption c) e. printstacktrace ();finally try if (con !二 null) con. close ();catch (sqlexception e) e. pri ntstacktrace ();private static void insertlogdata(connection con, int i) tbrows sqlexcepti on pr
35、cparcdsteitcment stmt 二con.preparestatement (insert logs query);/ message is very long, will throw sqlexceptionstmt. setstring(l, "employee information saved successfully for + i);stmt. cxccutcupdatc ();system, out. println(zzlogs data inserted successfully for id二 + i);stmt, close ();這段程序非常容易理
36、解。在數(shù)據(jù)成功插入employee表和address表后,創(chuàng)建了 一個savepointo如果拋出sqlexception,而savepoint為空,意味著在執(zhí)行插 入employee或者address表時發(fā)生了異常,所以需要冋滾整個事務(wù)。如果savepoint不為空,意味著sqlexception由插入日志表logs操作引發(fā),所 以只回滾事務(wù)到保存點,然后捉交。運行上面的程序,可以看到下面的輸出信息:db connection created successfullyemployee data inserted successfully for id=2 address data inserted successfully for id=2 com. mysql. jdbc. mysq
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 江蘇省南京市2024-2025學(xué)年高一上學(xué)期期末學(xué)情調(diào)研數(shù)學(xué)試卷(含答案)
- 2024-2025學(xué)年北京市順義區(qū)第二中學(xué)高三上學(xué)期12月月考數(shù)學(xué)試題(含答案)
- 2022高考英語完形填空和閱讀理解暑假選練(4)答案(外研版)
- 【名師伴你行】2021屆高考物理二輪復(fù)習(xí)專題提能專訓(xùn):16機(jī)械振動、機(jī)械波、光及光的波動性
- 項目管理試用期總結(jié):回顧成長路上的收獲與挑戰(zhàn)
- 2022高考英語溫州市信息匹配、閱理自練及答案2
- 【KS5U原創(chuàng)】新課標(biāo)2021年高一英語暑假作業(yè)7
- 四年級數(shù)學(xué)(簡便運算)計算題專項練習(xí)與答案
- 2021街道社區(qū)矯正工作匯報材料
- 云南省德宏州潞西市芒市中學(xué)2014-2021學(xué)年高中生物必修三教案-2.2通過激素調(diào)節(jié)
- 2025北京朝陽初二(上)期末數(shù)學(xué)真題試卷(含答案解析)
- 做賬實操-科學(xué)研究和技術(shù)服務(wù)業(yè)的賬務(wù)處理示例
- 2025年人教版歷史八上期末復(fù)習(xí)-全冊重難點知識
- 2024年國家安全員資格考試題庫及解析答案
- 山東省濱州市2023-2024學(xué)年高一上學(xué)期1月期末考試 政治 含答案
- 儀控技術(shù)手冊-自控專業(yè)工程設(shè)計用典型條件表
- 法務(wù)崗位招聘筆試題及解答(某大型國企)2025年
- 《慶澳門回歸盼祖國統(tǒng)一》主題班會教案
- 洗衣房工作人員崗位職責(zé)培訓(xùn)
- 廣東省深圳市光明區(qū)2022-2023學(xué)年五年級上學(xué)期數(shù)學(xué)期末試卷(含答案)
- XX小區(qū)春節(jié)燈光布置方案
評論
0/150
提交評論