事務(wù)

問題:事務(wù)是什么牛欢,有什么用?

事務(wù)就是一個事情,組成這個事情可能有多個單元淆游,要求這些單元傍睹,要么全都成功,要么全都不成功犹菱。

在開發(fā)中焰望,有事務(wù)的存在,可以保證數(shù)據(jù)完整性已亥。

問題:事務(wù)怎樣操作

創(chuàng)建表:

create table account(

id int primary key auto_increment,

name varchar(20),

money double

);

insert into account values(null,'aaa',1000);

insert into account values(null,'bbb',1000);

insert into account values(null,'ccc',1000);

1.mysql下怎樣操作

方式1:

start transaction? 開啟事務(wù)

rollback 事務(wù)回滾

commit 事務(wù)提交

方式2:

show variables like '%commit%'; 可以查看當(dāng)前autocommit值

在mysql數(shù)據(jù)庫中它的默認(rèn)值是"on"代表自動事務(wù).

自動事務(wù)的意義就是:執(zhí)行任意一條sql語句都會自動提交事務(wù).

測試:將autocommit的值設(shè)置為off

1.set autocommit=off 關(guān)閉自動事務(wù)熊赖。

2.必須手動commit才可以將事務(wù)提交。

注意:mysql默認(rèn)autocommit=on? oracle默認(rèn)的autocommit=off;

2.jdbc下怎樣操作

java.sql.Connection接口中有幾個方法是用于可以操作事務(wù)

1.setAutocommit(boolean flag);

如果flag=false;它就相當(dāng)于start transaction;

2.rollBack()

事務(wù)回滾虑椎。

3.commit()

事務(wù)提交


事務(wù)特性(重點) ACID

? 原子性(Atomicity)

原子性是指事務(wù)是一個不可分割的工作單位震鹉,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生捆姜。

? 一致性(Consistency)

事務(wù)前后數(shù)據(jù)的完整性必須保持一致传趾。

? 隔離性(Isolation)

事務(wù)的隔離性是指多個用戶并發(fā)訪問數(shù)據(jù)庫時,一個用戶的事務(wù)不能被其它用戶的事務(wù)所干擾泥技,多個并發(fā)事務(wù)之間數(shù)據(jù)要相互隔離浆兰。

? 持久性(Durability)

持久性是指一個事務(wù)一旦被提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的珊豹,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響

-------------------------------------

如果不考慮事務(wù)的隔離性簸呈,會出現(xiàn)什么問題?

1.臟讀 一個事務(wù)讀取到另一個事務(wù)的未提交數(shù)據(jù)。

2.不可重復(fù)讀

兩次讀取的數(shù)據(jù)不一致(update)

3.虛讀(幻讀)

兩次讀取的數(shù)據(jù)一一致(insert)

4.丟失更新

兩個事務(wù)對同一條記錄進(jìn)行操作店茶,后提交的事務(wù)蜕便,將先提交的事務(wù)的修改覆蓋了。

-----------------------------------------

演示以上問題贩幻,以及問題的解決方案

對于以上的問題轿腺,我們可以通過設(shè)置事務(wù)的隔離級別來解決。

1.事務(wù)的隔離級別有哪些?

1 Serializable:可避免臟讀丛楚、不可重復(fù)讀族壳、虛讀情況的發(fā)生。(串行化)

2 Repeatable read:可避免臟讀趣些、不可重復(fù)讀情況的發(fā)生仿荆。(可重復(fù)讀)不可以避免虛讀

3 Read committed:可避免臟讀情況發(fā)生(讀已提交)

4 Read uncommitted:最低級別,以上情況均無法保證。(讀未提交)

2.怎樣設(shè)置事務(wù)的隔離級別?

1.mysql中設(shè)置

1.查看事務(wù)隔離級別

select @@tx_isolation 查詢當(dāng)前事務(wù)隔離級別

mysql中默認(rèn)的事務(wù)隔離級別是? Repeatable read.

擴(kuò)展:oracle 中默認(rèn)的事務(wù)隔離級別是? Read committed

2.mysql中怎樣設(shè)置事務(wù)隔離級別

set session transaction isolation level 設(shè)置事務(wù)隔離級別

2.jdbc中設(shè)置

在jdbc中設(shè)置事務(wù)隔離級別

使用java.sql.Connection接口中提供的方法

void setTransactionIsolation(int level) throws SQLException

參數(shù)level可以取以下值:

level - 以下 Connection 常量之一:

Connection.TRANSACTION_READ_UNCOMMITTED赖歌、

Connection.TRANSACTION_READ_COMMITTED枉圃、

Connection.TRANSACTION_REPEATABLE_READ

Connection.TRANSACTION_SERIALIZABLE。

(注意庐冯,不能使用 Connection.TRANSACTION_NONE孽亲,因為它指定了不受支持的事務(wù)。)

--------------------------------------------------

3.演示

1.臟讀

一個事務(wù)讀取到另一個事務(wù)的為提交數(shù)據(jù)

設(shè)置A,B事務(wù)隔離級別為? Read uncommitted

set session transaction isolation level? read uncommitted;

1.在A事務(wù)中

start transaction;

update account set money=money-500 where name='aaa';

update account set money=money+500 where name='bbb';

2.在B事務(wù)中

start transaction;

select * from account;

這時展父,B事務(wù)讀取時返劲,會發(fā)現(xiàn),錢已經(jīng)匯完栖茉。那么就出現(xiàn)了臟讀篮绿。

當(dāng)A事務(wù)提交前,執(zhí)行rollback吕漂,在commit亲配, B事務(wù)在查詢,就會發(fā)現(xiàn)惶凝,錢恢復(fù)成原樣

也出現(xiàn)了兩次查詢結(jié)果不一致問題吼虎,出現(xiàn)了不可重復(fù)讀.

2.解決臟讀問題

將事務(wù)的隔離級別設(shè)置為 read committed來解決臟讀

設(shè)置A,B事務(wù)隔離級別為? Read committed

set session transaction isolation level? read committed;

1.在A事務(wù)中

start transaction;

update account set money=money-500 where name='aaa';

update account set money=money+500 where name='bbb';

2.在B事務(wù)中

start transaction;

select * from account;

這時B事務(wù)中,讀取信息時苍鲜,是不能讀到A事務(wù)未提交的數(shù)據(jù)的思灰,也就解決了臟讀。

讓A事務(wù)混滔,提交數(shù)據(jù) commit;

這時洒疚,在查詢,這次結(jié)果與上一次查詢結(jié)果又不一樣了坯屿,還存在不可重復(fù)讀油湖。

3.解決不可重復(fù)讀

將事務(wù)的隔離級別設(shè)置為Repeatable read來解決不可重復(fù)讀。

設(shè)置A,B事務(wù)隔離級別為? Repeatable read;

set session transaction isolation level? Repeatable read;

1.在A事務(wù)中

start transaction;

update account set money=money-500 where name='aaa';

update account set money=money+500 where name='bbb';

2.在B事務(wù)中

start transaction;

select * from account;

當(dāng)A事務(wù)提交后commit;B事務(wù)在查詢愿伴,與上次查詢結(jié)果一致肺魁,解決了不可重復(fù)讀电湘。

4.設(shè)置事務(wù)隔離級別 Serializable ,它可以解決所有問題

set session transaction isolation level Serializable;

如果設(shè)置成這種隔離級別隔节,那么會出現(xiàn)鎖表。也就是說寂呛,一個事務(wù)在對表進(jìn)行操作時怎诫,

其它事務(wù)操作不了。

--------------------------------------------------

總結(jié):

臟讀:一個事務(wù)讀取到另一個事務(wù)為提交數(shù)據(jù)

不可重復(fù)讀:兩次讀取數(shù)據(jù)不一致(讀提交數(shù)據(jù))---update

虛讀:兩次讀取數(shù)據(jù)不一致(讀提交數(shù)據(jù))----insert

事務(wù)隔離級別:

read uncommitted 什么問題也解決不了.

read committed 可以解決臟讀贷痪,其它解決不了.

Repeatable read 可以解決臟讀幻妓,可以解決不可重復(fù)讀,不能解決虛讀.

Serializable 它會鎖表,可以解決所有問題.

安全性:serializable > repeatable read > read committed > read uncommitted

性能 :serializable < repeatable read < read committed < read uncommitted

結(jié)論: 實際開發(fā)中劫拢,通常不會選擇 serializable 和 read uncommitted 肉津,

mysql默認(rèn)隔離級別 repeatable read 强胰,oracle默認(rèn)隔離級別 read committed


==========================================================================================

案例:轉(zhuǎn)賬匯款----使用事務(wù)

問題:service調(diào)用了dao中兩個方法完成了一個業(yè)務(wù)操作,如果其中一個方法執(zhí)行失敗怎樣辦?

需要事務(wù)控制

問題:怎樣進(jìn)行事務(wù)控制?

我們在service層進(jìn)行事務(wù)的開啟妹沙,回滾以及提交操作偶洋。

問題:進(jìn)行事務(wù)操作需要使用Connection對象,那么距糖,怎樣保證玄窝,在service中與dao中所使用的是同一個Connection.

在service層創(chuàng)建出Connection對象,將這個對象傳遞到dao層.

注意:Connecton對象使用完成后悍引,在service層的finally中關(guān)閉

而每一個PreparedStatement它們在dao層的方法中用完就關(guān)閉.

關(guān)于程序問題

1.對于轉(zhuǎn)入與轉(zhuǎn)出操作恩脂,我們需要判斷是否成功,如果失敗了趣斤,可以通過拋出自定義異常在servlet中判斷俩块,

進(jìn)行信息展示 。

----------------------------------------------------------問題:在設(shè)置dao層時浓领,public interface AccountDao {public void accountOut(String accountOut, double money) throws Exception;public void accountIn(String accountIn, double money) throws Exception;}那么我們自己去實現(xiàn)這個接口時典阵,怎樣處理,同一個Connection對象問題?使用ThreadLocalThreadLocal可以理解成是一個Map集合Mapset方法是向ThreadLocal中存儲數(shù)據(jù)镊逝,那么當(dāng)前的key值就是當(dāng)前線程對象.get方法是從ThreadLocal中獲取數(shù)據(jù)壮啊,它是根據(jù)當(dāng)前線程對象來獲取值。如果我們是在同一個線程中撑蒜,只要在任意的一個位置存儲了數(shù)據(jù)歹啼,在其它位置上,就可以獲取到這個數(shù)據(jù)座菠。關(guān)于JdbcUtils中使用ThreadLocal1.聲明一個ThreadLocalprivate static final ThreadLocaltl = new ThreadLocal();

2.在getConnection()方法中操作

Connection con = tl.get(); 直接從ThreadLocal中獲取狸眼,第一次返回的是null.

if (con == null) {

// 2.獲取連接

con = DriverManager.getConnection(URL, USERNAME, PASSWORD);

tl.set(con); //將con裝入到ThreadLocal中。

}

==========================================================================================

丟失更新

多個事務(wù)對同一條記錄進(jìn)行了操作浴滴,后提交的事務(wù)將先提交的事務(wù)操作覆蓋了拓萌。

查看圖.

問題:怎樣解決丟失更新問題?

解決丟失更新可以采用兩種方式:

1.悲觀鎖

悲觀鎖 (假設(shè)丟失更新一定會發(fā)生 ) ----- 利用數(shù)據(jù)庫內(nèi)部鎖機(jī)制,管理事務(wù)

提供的鎖機(jī)制

1.共享鎖

select * from table lock in share mode(讀鎖升略、共享鎖)

2.排它鎖

select * from table for update (寫鎖微王、排它鎖)

update語句默認(rèn)添加排它鎖

2.樂觀鎖

樂觀鎖 (假設(shè)丟失更新不會發(fā)生)------- 采用程序中添加版本字段解決丟失更新問題

create table product (

id int,

name varchar(20),

updatetime timestamp

);

insert into product values(1,'冰箱',null);

update product set name='洗衣機(jī)' where id = 1;

解決丟失更新:在數(shù)據(jù)表添加版本字段,每次修改過記錄后品嚣,版本字段都會更新炕倘,如果讀取是版本字段,

與修改時版本字段不一致翰撑,說明別人進(jìn)行修改過數(shù)據(jù) (重改)

===============================================================================================================

連接池 問題:連接池是什么罩旋,有什么用?

連接池:就是創(chuàng)建一個容器,用于裝入多個Connection對象,在使用連接對象時涨醋,從容器中獲取一個Connection瓜饥,? 使用完成后,在將這個Connection重新裝入到容器中浴骂。這個容器就是連接池压固。(DataSource)? 也叫做數(shù)據(jù)源.? 我們可以通過連接池獲取連接對象.優(yōu)點:節(jié)省創(chuàng)建連接與釋放連接 性能消耗 ---- 連接池中連接起到復(fù)用的作用 ,提高程序性能-----------------------------------------------------------------------------------自定義連接池

1.創(chuàng)建一個MyDataSource類靠闭,在這個類中創(chuàng)建一個LinkedList

2.在其構(gòu)造方法中初始化List集合帐我,并向其中裝入5個Connection對象。

3.創(chuàng)建一個public Connection getConnection();從List集合中獲取一個連接對象返回.

4.創(chuàng)建一個? public void readd(Connection) 這個方法是將使用完成后的Connection對象重新裝入到List集合中.

代碼問題:

1.連接池的創(chuàng)建是有標(biāo)準(zhǔn)的.

在javax.sql包下定義了一個接口 DataSource

簡單說愧膀,所有的連接池必須實現(xiàn)javax.sql.DataSource接口拦键,

我們的自定義連接池必須實現(xiàn)DataSource接口。

2.我們操作時檩淋,要使用標(biāo)準(zhǔn)芬为,怎樣可以讓 con.close()它不是銷毀,而是將其重新裝入到連接池.

要解決這個問題蟀悦,其本質(zhì)就是將Connection中的close()方法的行為改變媚朦。

怎樣可以改變一個方法的行為(對方法功能進(jìn)行增強(qiáng))

1.繼承

2.裝飾模式

1.裝飾類與被裝飾類要實現(xiàn)同一個接口或繼承同一個父類

2.在裝飾類中持有一個被裝飾類引用

3.對方法進(jìn)行功能增強(qiáng)。

3.動態(tài)代理

可以對行為增強(qiáng)

Proxy.newProxyInstance(ClassLoacer ,Class[],InvocationHandler);

結(jié)論:Connection對象如果是從連接池中獲取到的日戈,那么它的close方法的行為已經(jīng)改變了询张,不在是銷毀,而是重新裝入到連接池浙炼。

--------------------------------------------------------------------

1.連接池必須實現(xiàn)javax.sql.DataSource接口份氧。

2.要通過連接池獲取連接對象? DataSource接口中有一個? getConnection方法.

3.將Connection重新裝入到連接池? 使用Connection的close()方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弯屈,一起剝皮案震驚了整個濱河市蜗帜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌资厉,老刑警劉巖厅缺,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宴偿,居然都是意外死亡湘捎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門酪我,熙熙樓的掌柜王于貴愁眉苦臉地迎上來消痛,“玉大人,你說我怎么就攤上這事都哭。” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵欺矫,是天一觀的道長纱新。 經(jīng)常有香客問我,道長穆趴,這世上最難降的妖魔是什么脸爱? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮未妹,結(jié)果婚禮上簿废,老公的妹妹穿的比我還像新娘。我一直安慰自己络它,他們只是感情好族檬,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著化戳,像睡著了一般单料。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上点楼,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天扫尖,我揣著相機(jī)與錄音,去河邊找鬼掠廓。 笑死换怖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蟀瞧。 我是一名探鬼主播狰域,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼黄橘!你這毒婦竟也來了兆览?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤塞关,失蹤者是張志新(化名)和其女友劉穎抬探,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帆赢,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡小压,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年降瞳,在試婚紗的時候發(fā)現(xiàn)自己被綠了尔崔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡忧换,死狀恐怖瘾婿,靈堂內(nèi)的尸體忽然破棺而出蜻牢,到底是詐尸還是另有隱情烤咧,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布抢呆,位于F島的核電站煮嫌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抱虐。R本人自食惡果不足惜昌阿,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望恳邀。 院中可真熱鬧懦冰,春花似錦、人聲如沸谣沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳄抒。三九已至闯捎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間许溅,已是汗流浹背瓤鼻。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留贤重,地道東北人茬祷。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像并蝗,于是被迫代替她去往敵國和親祭犯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 一滚停、什么是事務(wù) 邏輯上的一組操作, 沃粗,要不全部失敗,要不全部成功键畴。 MySql的事務(wù)管理 在事務(wù)管理中執(zhí)行sql最盅,...
    明天你好向前奔跑閱讀 797評論 0 4
  • 一、事務(wù) 事務(wù)就是一個事情起惕,組成這個事情可能有多個單元涡贱,要求這些單元,要么全都成功惹想,要么全都不成功问词。在開發(fā)中,有事...
    野狗子嗷嗷嗷閱讀 2,797評論 0 6
  • 本文包括:1嘀粱、事務(wù)概念2激挪、MySQL管理事務(wù)3辰狡、JDBC控制事務(wù)進(jìn)程4、事務(wù)的特性(ACID)5灌灾、事務(wù)的隔離級別6...
    廖少少閱讀 825評論 0 3
  • 很多人喜歡這篇文章搓译,特此同步過來 由淺入深談?wù)搒pring事務(wù) 前言 這篇其實也要歸納到《常識》系列中悲柱,但這重點又...
    碼農(nóng)戲碼閱讀 4,706評論 2 59
  • 事務(wù) 1.事務(wù)的概念: 事務(wù)是指邏輯上的一組操作锋喜,這組操作要么同時完成要么同時不完成。參考轉(zhuǎn)賬操作豌鸡。 2. 如果你...
    PASSssss閱讀 287評論 0 0