欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis update數(shù)據(jù)庫(kù)死鎖之獲取數(shù)據(jù)庫(kù)連接池等待

 更新時(shí)間:2016年07月22日 10:11:56   作者:Ryan.Miao  
這篇文章主要介紹了Mybatis update數(shù)據(jù)庫(kù)死鎖之獲取數(shù)據(jù)庫(kù)連接池等待的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

 最近學(xué)習(xí)測(cè)試mybatis,單個(gè)增刪改查都沒(méi)問(wèn)題,最后使用mvn test的時(shí)候發(fā)現(xiàn)了幾個(gè)問(wèn)題:

1.update失敗,原因是數(shù)據(jù)庫(kù)死鎖

2.select等待,原因是connection連接池被用光了,需要等待

get:

1.要勇于探索,堅(jiān)持就是勝利。剛看到錯(cuò)誤的時(shí)候直接懵逼,因?yàn)殄e(cuò)誤完全看不出來(lái),屬于框架內(nèi)部報(bào)錯(cuò),在猶豫是不是直接睡

覺(jué)得了,畢竟也快12點(diǎn)了。最后還是給我一點(diǎn)點(diǎn)找到問(wèn)題所在了。

2.同上,要敢于去深入你不了解的代碼,敢于研究不懂的代碼。

3.距離一個(gè)合格的碼農(nóng)越來(lái)越遠(yuǎn)了,因?yàn)樵綄W(xué)越覺(jué)得漏洞百出,自己的代碼到處都是坑。所以,一定要記錄下來(lái)。

下面記錄這兩個(gè)問(wèn)題。

1.mysql數(shù)據(jù)庫(kù)死鎖

這里,感謝http://www.cnblogs.com/lin-xuan/p/5280614.html,我找到了答案。在這里,我還是重現(xiàn)一下:

數(shù)據(jù)庫(kù)死鎖是事務(wù)性數(shù)據(jù)庫(kù) (如SQL Server, MySql等)經(jīng)常遇到的問(wèn)題。除非數(shù)據(jù)庫(kù)死鎖問(wèn)題頻繁出現(xiàn)導(dǎo)致用戶無(wú)法操作,一般情況下數(shù)據(jù)庫(kù)死鎖問(wèn)題不嚴(yán)重。在應(yīng)用程序中進(jìn)行try-catch就可以。那么數(shù)據(jù)死鎖是如何產(chǎn)生的呢?

InnoDB實(shí)現(xiàn)的是行鎖 (row level lock),分為共享鎖 (S) 和 互斥鎖 (X)。

•共享鎖用于事務(wù)read一行。
•互斥鎖用于事務(wù)update或delete一行。

當(dāng)客戶A持有共享鎖S,并請(qǐng)求互斥鎖X;同時(shí)客戶B持有互斥鎖X,并請(qǐng)求共享鎖S。以上情況,會(huì)發(fā)生數(shù)據(jù)庫(kù)死鎖。如果還不夠清楚,請(qǐng)看下面的例子。

雙開(kāi)兩個(gè)mysql客戶端

客戶端A:

開(kāi)啟事務(wù),并鎖定共享鎖S 在id=12的時(shí)候:

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM blog WHERE id = 12 LOCK IN SHARE MODE;
+----+-------+-----------+
| id | name | author_id |
+----+-------+-----------+
| 12 | testA | 50 |
+----+-------+-----------+
1 row in set (0.00 sec)

客戶端B:

開(kāi)啟事務(wù),嘗試刪除id=12:

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> DELETE FROM blog WHERE id = 12;

刪除操作需要互斥鎖 (X),但是互斥鎖X和共享鎖S是不能相容的。所以刪除事務(wù)被放到鎖請(qǐng)求隊(duì)列中,客戶B阻塞。

這時(shí)候客戶端A也想要?jiǎng)h除12:

mysql> DELETE FROM blog WHERE id = 12;
Query OK, 1 row affected (0.00 sec)

和參考文章不同的是,居然刪除成功了,但客戶端B出錯(cuò)了:

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

于是,我嘗試刪除13,這下都阻塞了:

我的mybatis測(cè)試代碼中,因?yàn)樯弦粋€(gè)測(cè)試沒(méi)有commit導(dǎo)致死鎖,commit后就ok了。在這里,我想說(shuō),數(shù)據(jù)庫(kù)的東西全還給老師了,關(guān)于鎖以及事務(wù)需要重新溫習(xí)一下了。

2.Mybatis中datasource的數(shù)據(jù)庫(kù)連接數(shù)

當(dāng)我mvn test的時(shí)候,我發(fā)現(xiàn)有個(gè)查詢的test打印日志:

2016-07-21 23:43:53,356 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Opening JDBC Connection
2016-07-21 23:43:53,356 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - Waiting as long as 20000 milliseconds for connection.

于是,果然等了一段時(shí)間后才執(zhí)行成功。跟蹤源碼,找到這處日志就明白了。首先,我這里使用的數(shù)據(jù)庫(kù)連接配置是mybatis默認(rèn)的:

<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment> 
當(dāng)數(shù)據(jù)庫(kù)連接池的連接數(shù)用光了之后就要等2s再去獲?。?
while (conn == null) {
synchronized (state) {
if (!state.idleConnections.isEmpty()) {
// Pool has available connection
conn = state.idleConnections.remove(0);
if (log.isDebugEnabled()) {
log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
}
} else {
// Pool does not have available connection
if (state.activeConnections.size() < poolMaximumActiveConnections) {
// Can create new connection
conn = new PooledConnection(dataSource.getConnection(), this);
if (log.isDebugEnabled()) {
log.debug("Created connection " + conn.getRealHashCode() + ".");
}
} else {
// Cannot create new connection
PooledConnection oldestActiveConnection = state.activeConnections.get(0);
long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
if (longestCheckoutTime > poolMaximumCheckoutTime) {
// Can claim overdue connection
state.claimedOverdueConnectionCount++;
state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
state.accumulatedCheckoutTime += longestCheckoutTime;
state.activeConnections.remove(oldestActiveConnection);
if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
try {
oldestActiveConnection.getRealConnection().rollback();
} catch (SQLException e) {
log.debug("Bad connection. Could not roll back");
} 
}
conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
oldestActiveConnection.invalidate();
if (log.isDebugEnabled()) {
log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
}
} else {
// Must wait
try {
if (!countedWait) {
state.hadToWaitCount++;
countedWait = true;
}
if (log.isDebugEnabled()) {
log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection.");
}
long wt = System.currentTimeMillis();
state.wait(poolTimeToWait);
state.accumulatedWaitTime += System.currentTimeMillis() - wt;
} catch (InterruptedException e) {
break;
}
}
}
}
if (conn != null) {
if (conn.isValid()) {
if (!conn.getRealConnection().getAutoCommit()) {
conn.getRealConnection().rollback();
}
conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));
conn.setCheckoutTimestamp(System.currentTimeMillis());
conn.setLastUsedTimestamp(System.currentTimeMillis());
state.activeConnections.add(conn);
state.requestCount++;
state.accumulatedRequestTime += System.currentTimeMillis() - t;
} else {
if (log.isDebugEnabled()) {
log.debug("A bad connection (" + conn.getRealHashCode() + ") was returned from the pool, getting another connection.");
}
state.badConnectionCount++;
localBadConnectionCount++;
conn = null;
if (localBadConnectionCount > (poolMaximumIdleConnections + 3)) {
if (log.isDebugEnabled()) {
log.debug("PooledDataSource: Could not get a good connection to the database.");
}
throw new SQLException("PooledDataSource: Could not get a good connection to the database.");
}
}
}
}
}

當(dāng)連接數(shù)少于10個(gè)的時(shí)候回創(chuàng)建,超過(guò)10個(gè)就會(huì)等待,不然就報(bào)錯(cuò)。

以上所述是小編給大家介紹的Mybatis update數(shù)據(jù)庫(kù)死鎖之獲取數(shù)據(jù)庫(kù)連接池等待,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • java結(jié)束當(dāng)前循環(huán)常用代碼

    java結(jié)束當(dāng)前循環(huán)常用代碼

    在?Java中,當(dāng)我們要結(jié)束一個(gè)循環(huán)時(shí),通常會(huì)使用循環(huán)變量的實(shí)現(xiàn)類(lèi)來(lái)結(jié)束,但在實(shí)際開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到某個(gè)循環(huán)結(jié)束后需要進(jìn)行其他的操作的情況,在本文中給大家分享java結(jié)束當(dāng)前循環(huán)常用代碼,感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • 基于@RequestBody和@ResponseBody及Stringify()的作用說(shuō)明

    基于@RequestBody和@ResponseBody及Stringify()的作用說(shuō)明

    這篇文章主要介紹了基于@RequestBody和@ResponseBody及Stringify()的作用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Springboot 中使用 Aop代碼實(shí)戰(zhàn)教程

    Springboot 中使用 Aop代碼實(shí)戰(zhàn)教程

    AOP的編程思想是把對(duì)類(lèi)對(duì)象的橫切問(wèn)題點(diǎn),從業(yè)務(wù)邏輯中分離出來(lái),從而達(dá)到解耦的目的,增加代碼的復(fù)用性,提高開(kāi)發(fā)效率,這篇文章主要介紹了Springboot中使用Aop代碼實(shí)戰(zhàn)教程,需要的朋友可以參考下
    2023-07-07
  • 原生Java操作mysql數(shù)據(jù)庫(kù)過(guò)程解析

    原生Java操作mysql數(shù)據(jù)庫(kù)過(guò)程解析

    這篇文章主要介紹了原生Java操作mysql數(shù)據(jù)庫(kù)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 淺談一下maven優(yōu)缺點(diǎn)及使用和特點(diǎn)

    淺談一下maven優(yōu)缺點(diǎn)及使用和特點(diǎn)

    這篇文章主要介紹了淺談一下maven優(yōu)缺點(diǎn)及使用和特點(diǎn),一個(gè)項(xiàng)目管理工具軟件,那么maven項(xiàng)目有什么優(yōu)缺點(diǎn)呢,讓我們一起來(lái)看看吧
    2023-03-03
  • Spring Cloud Gateway(讀取、修改 Request Body)的操作

    Spring Cloud Gateway(讀取、修改 Request Body)的操作

    這篇文章主要介紹了Spring Cloud Gateway(讀取、修改 Request Body)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫(kù)分庫(kù)分表操作和總結(jié)(推薦)

    MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫(kù)分庫(kù)分表操作和總結(jié)(推薦)

    這篇文章主要介紹了MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫(kù)分庫(kù)分表操作和總結(jié),需要的朋友可以參考下
    2017-08-08
  • SpringAOP實(shí)現(xiàn)自定義接口權(quán)限控制

    SpringAOP實(shí)現(xiàn)自定義接口權(quán)限控制

    本文主要介紹了SpringAOP實(shí)現(xiàn)自定義接口權(quán)限控制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11
  • java基于netty NIO的簡(jiǎn)單聊天室的實(shí)現(xiàn)

    java基于netty NIO的簡(jiǎn)單聊天室的實(shí)現(xiàn)

    這篇文章主要介紹了java基于netty NIO的簡(jiǎn)單聊天室的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java NIO原理圖文分析及代碼實(shí)現(xiàn)

    Java NIO原理圖文分析及代碼實(shí)現(xiàn)

    本文主要介紹Java NIO原理的知識(shí),這里整理了詳細(xì)資料及簡(jiǎn)單示例代碼和原理圖,有需要的小伙伴可以參考下
    2016-09-09

最新評(píng)論