Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
b3b45da6
提交
b3b45da6
authored
16 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Sometimes a StackOverflow occured when checking for deadlock.
上级
8cff8c47
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
68 行增加
和
14 行删除
+68
-14
changelog.html
h2/src/docsrc/html/changelog.html
+3
-1
Table.java
h2/src/main/org/h2/table/Table.java
+5
-4
TableData.java
h2/src/main/org/h2/table/TableData.java
+6
-3
TestDeadlock.java
h2/src/test/org/h2/test/db/TestDeadlock.java
+54
-6
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
b3b45da6
...
...
@@ -18,7 +18,9 @@ Change Log
<h1>
Change Log
</h1>
<h2>
Next Version (unreleased)
</h2>
<ul><li>
The Shell tool does no longer truncate results with only one column, and displays
<ul><li>
Sometimes a StackOverflow occured when checking for deadlock. See also
http://code.google.com/p/h2database/issues/detail?id=61
</li><li>
The Shell tool does no longer truncate results with only one column, and displays
a message if data was truncated.
</li></ul>
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/Table.java
浏览文件 @
b3b45da6
...
...
@@ -9,6 +9,7 @@ package org.h2.table;
import
java.sql.SQLException
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.h2.command.Prepared
;
import
org.h2.constant.ErrorCode
;
...
...
@@ -884,16 +885,16 @@ public abstract class Table extends SchemaObjectBase {
/**
* Check if a deadlock occurred. This method is called recursively. There is
* a circle if the session to be tested
for is the same as the originating
*
session (the 'clash session
'). In this case the method must return an
* a circle if the session to be tested
has already being visited (i.e., it
*
is one of the 'clash sessions
'). In this case the method must return an
* empty object array. Once a deadlock has been detected, the methods must
* add the session to the list.
*
* @param session the session to be tested for
* @param clash
the originating session
, and null when starting verification
* @param clash
set with sessions already visited
, and null when starting verification
* @return an object array with the sessions involved in the deadlock
*/
public
ObjectArray
checkDeadlock
(
Session
session
,
Se
ssion
clash
)
{
public
ObjectArray
checkDeadlock
(
Session
session
,
Se
t
clash
)
{
return
null
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/TableData.java
浏览文件 @
b3b45da6
...
...
@@ -10,6 +10,7 @@ import java.sql.SQLException;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.Set
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.constant.ErrorCode
;
...
...
@@ -379,6 +380,7 @@ public class TableData extends Table implements RecordReader {
}
private
void
doLock
(
Session
session
,
int
lockMode
,
boolean
exclusive
)
throws
SQLException
{
traceLock
(
session
,
exclusive
,
"requesting for"
);
long
max
=
System
.
currentTimeMillis
()
+
session
.
getLockTimeout
();
boolean
checkDeadlock
=
false
;
while
(
true
)
{
...
...
@@ -486,16 +488,17 @@ public class TableData extends Table implements RecordReader {
return
buff
.
toString
();
}
public
ObjectArray
checkDeadlock
(
Session
session
,
Se
ssion
clash
)
{
public
ObjectArray
checkDeadlock
(
Session
session
,
Se
t
clash
)
{
// only one deadlock check at any given time
synchronized
(
TableData
.
class
)
{
if
(
clash
==
null
)
{
// verification is started
clash
=
session
;
}
else
if
(
clash
==
session
)
{
clash
=
new
HashSet
()
;
}
else
if
(
clash
.
contains
(
session
)
)
{
// we found a circle
return
new
ObjectArray
();
}
clash
.
add
(
session
);
ObjectArray
error
=
null
;
for
(
Iterator
it
=
lockShared
.
iterator
();
it
.
hasNext
();)
{
Session
s
=
(
Session
)
it
.
next
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestDeadlock.java
浏览文件 @
b3b45da6
...
...
@@ -48,6 +48,7 @@ public class TestDeadlock extends TestBase {
testLockUpgrade
();
testThreePhilosophers
();
testNoDeadlock
();
testThreeSome
();
deleteDb
(
"deadlock"
);
}
...
...
@@ -180,7 +181,7 @@ public class TestDeadlock extends TestBase {
}
t2
.
join
();
t3
.
join
();
checkDeadlock
();
checkDeadlock
(
1
);
c1
.
commit
();
c2
.
commit
();
c3
.
commit
();
...
...
@@ -188,6 +189,51 @@ public class TestDeadlock extends TestBase {
end
();
}
// test case for issue # 61
// http://code.google.com/p/h2database/issues/detail?id=61)
private
void
testThreeSome
()
throws
Exception
{
if
(
config
.
mvcc
)
{
return
;
}
initTest
();
c1
.
createStatement
().
execute
(
"CREATE TABLE TEST_A(ID INT PRIMARY KEY)"
);
c1
.
createStatement
().
execute
(
"CREATE TABLE TEST_B(ID INT PRIMARY KEY)"
);
c1
.
createStatement
().
execute
(
"CREATE TABLE TEST_C(ID INT PRIMARY KEY)"
);
c1
.
commit
();
c1
.
createStatement
().
execute
(
"INSERT INTO TEST_A VALUES(1)"
);
c1
.
createStatement
().
execute
(
"INSERT INTO TEST_B VALUES(1)"
);
c2
.
createStatement
().
execute
(
"INSERT INTO TEST_C VALUES(1)"
);
DoIt
t2
=
new
DoIt
()
{
public
void
execute
()
throws
SQLException
{
c3
.
createStatement
().
execute
(
"INSERT INTO TEST_B VALUES(2)"
);
c3
.
commit
();
}
};
t2
.
start
();
DoIt
t3
=
new
DoIt
()
{
public
void
execute
()
throws
SQLException
{
c2
.
createStatement
().
execute
(
"INSERT INTO TEST_A VALUES(2)"
);
c2
.
commit
();
}
};
t3
.
start
();
try
{
c1
.
createStatement
().
execute
(
"INSERT INTO TEST_C VALUES(2)"
);
c1
.
commit
();
}
catch
(
SQLException
e
)
{
catchDeadlock
(
e
);
c1
.
rollback
();
}
t2
.
join
();
t3
.
join
();
checkDeadlock
(
2
);
c1
.
commit
();
c2
.
commit
();
c3
.
commit
();
c1
.
createStatement
().
execute
(
"DROP TABLE TEST_A, TEST_B, TEST_C"
);
end
();
}
private
void
testLockUpgrade
()
throws
Exception
{
if
(
config
.
mvcc
)
{
return
;
...
...
@@ -214,7 +260,7 @@ public class TestDeadlock extends TestBase {
catchDeadlock
(
e
);
}
t1
.
join
();
checkDeadlock
();
checkDeadlock
(
1
);
c1
.
commit
();
c2
.
commit
();
c1
.
createStatement
().
execute
(
"DROP TABLE TEST"
);
...
...
@@ -243,21 +289,23 @@ public class TestDeadlock extends TestBase {
catchDeadlock
(
e
);
}
t1
.
join
();
checkDeadlock
();
checkDeadlock
(
1
);
c1
.
commit
();
c2
.
commit
();
c1
.
createStatement
().
execute
(
"DROP TABLE T1, T2"
);
end
();
}
private
void
checkDeadlock
()
throws
SQLException
{
private
void
checkDeadlock
(
int
max
)
throws
SQLException
{
assertTrue
(
lastException
!=
null
);
assertKnownException
(
lastException
);
assertEquals
(
ErrorCode
.
DEADLOCK_1
,
lastException
.
getErrorCode
());
SQLException
e2
=
lastException
.
getNextException
();
if
(
e2
!=
null
)
{
if
(
e2
!=
null
&&
max
==
1
)
{
// we have two exception, but there should only be one
throw
e2
;
SQLException
e3
=
new
SQLException
(
"Expected one exception, got multiple"
);
e3
.
initCause
(
e2
);
throw
e3
;
}
}
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论