激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

香港云服务器
服務(wù)器之家 - 編程語言 - JAVA教程 - Mybatis update數(shù)據(jù)庫死鎖之獲取數(shù)據(jù)庫連接池等待

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

2020-05-31 13:01Ryan.Miao JAVA教程

這篇文章主要介紹了Mybatis update數(shù)據(jù)庫死鎖之獲取數(shù)據(jù)庫連接池等待的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

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

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

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

get:

1.要勇于探索,堅持就是勝利。剛看到錯誤的時候直接懵逼,因為錯誤完全看不出來,屬于框架內(nèi)部報錯,在猶豫是不是直接睡

覺得了,畢竟也快12點了。最后還是給我一點點找到問題所在了。

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

3.距離一個合格的碼農(nóng)越來越遠(yuǎn)了,因為越學(xué)越覺得漏洞百出,自己的代碼到處都是坑。所以,一定要記錄下來。

下面記錄這兩個問題。

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

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

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

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

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

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

雙開兩個mysql客戶端

客戶端A:

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

?
1
2
3
4
5
6
7
8
9
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:

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

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

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

這時候客戶端A也想要刪除12:

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

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

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

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

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

我的mybatis測試代碼中,因為上一個測試沒有commit導(dǎo)致死鎖,commit后就ok了。在這里,我想說,數(shù)據(jù)庫的東西全還給老師了,關(guān)于鎖以及事務(wù)需要重新溫習(xí)一下了。

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

當(dāng)我mvn test的時候,我發(fā)現(xiàn)有個查詢的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.

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<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ù)庫連接池的連接數(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個的時候回創(chuàng)建,超過10個就會等待,不然就報錯。

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

原文鏈接:http://www.cnblogs.com/woshimrf/p/5693673.html

延伸 · 閱讀

精彩推薦
512
主站蜘蛛池模板: 国产成人高清成人av片在线看 | 欧美一级做a | 国产一级毛片国产 | 天堂成人国产精品一区 | 久久成人国产精品 | 午夜精品一区二区三区免费 | 综合激情网 | 国产视频在线观看一区二区三区 | 视频一区二区不卡 | 欧美日韩免费一区二区三区 | 羞羞羞网站| 成人免费在线视频播放 | 久久99精品久久久久久秒播蜜臀 | 一区二区三区四区免费看 | 欧美日韩视频第一页 | a黄在线观看 | 欧美性黄 | 欧美特一级片 | 一级免费黄色免费片 | 黄色久| 国产精品视频免费在线观看 | 久久久一区二区三区视频 | 国产羞羞视频免费在线观看 | 日本欧美一区二区三区在线观看 | 午夜精品小视频 | 男女羞羞视频在线观看免费 | 天天好比网 | 精品视频在线免费看 | 成人做爰高潮片免费视频韩国 | 国产宾馆3p国语对白 | 黑人一区 | av成人免费在线观看 | a视频在线免费观看 | 日韩精品中文字幕在线播放 | 在线播放免费人成毛片乱码 | 中国女人内谢69xxxx天美 | 国产精品久久久久一区二区 | 亚洲成人高清在线观看 | 日韩电影一区二区三区 | 蜜桃网在线观看 | 欧美成人小视频 |