Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
suliangchun
dbeaver
提交
be62fc82
D
dbeaver
项目概览
suliangchun
/
dbeaver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dbeaver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
be62fc82
编写于
3月 02, 2018
作者:
S
serge-rider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
#2201 Auto-recover after SQL execute
Former-commit-id:
0d5bb1fb
上级
527b3823
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
151 addition
and
97 deletion
+151
-97
plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/runtime/sql/SQLQueryJob.java
...r.core/src/org/jkiss/dbeaver/runtime/sql/SQLQueryJob.java
+102
-88
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/ModelPreferences.java
...dbeaver.model/src/org/jkiss/dbeaver/ModelPreferences.java
+1
-1
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBUtils.java
...ss.dbeaver.model/src/org/jkiss/dbeaver/model/DBUtils.java
+17
-3
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/DBRRunnableParametrized.java
.../jkiss/dbeaver/model/runtime/DBRRunnableParametrized.java
+30
-0
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/DBRRunnableWithProgress.java
.../jkiss/dbeaver/model/runtime/DBRRunnableWithProgress.java
+1
-5
未找到文件。
plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/runtime/sql/SQLQueryJob.java
浏览文件 @
be62fc82
...
...
@@ -62,6 +62,7 @@ import org.jkiss.dbeaver.ui.dialogs.exec.ExecutionQueueErrorResponse;
import
org.jkiss.dbeaver.utils.RuntimeUtils
;
import
org.jkiss.utils.CommonUtils
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
...
...
@@ -377,98 +378,16 @@ public class SQLQueryJob extends DataSourceJob
}
startTime
=
System
.
currentTimeMillis
();
DBCExecutionSource
source
=
new
AbstractExecutionSource
(
dataContainer
,
executionContext
,
partSite
.
getPart
(),
sqlQuery
);
final
DBCStatement
dbcStatement
=
DBUtils
.
makeStatement
(
source
,
session
,
DBCStatementType
.
SCRIPT
,
sqlQuery
,
rsOffset
,
rsMaxRows
);
curStatement
=
dbcStatement
;
int
statementTimeout
=
getDataSourceContainer
().
getPreferenceStore
().
getInt
(
DBeaverPreferences
.
STATEMENT_TIMEOUT
);
if
(
statementTimeout
>
0
)
{
try
{
dbcStatement
.
setStatementTimeout
(
statementTimeout
);
}
catch
(
Throwable
e
)
{
log
.
debug
(
"Can't set statement timeout:"
+
e
.
getMessage
());
}
}
// Execute statement
try
{
session
.
getProgressMonitor
().
subTask
(
"Execute query"
);
boolean
hasResultSet
=
dbcStatement
.
executeStatement
();
curResult
.
setHasResultSet
(
hasResultSet
);
statistics
.
addExecuteTime
(
System
.
currentTimeMillis
()
-
startTime
);
statistics
.
addStatementsCount
();
long
updateCount
=
-
1
;
while
(
hasResultSet
||
resultSetNumber
==
0
||
updateCount
>=
0
)
{
// Fetch data only if we have to fetch all results or if it is rs requested
if
(
fetchResultSetNumber
<
0
||
fetchResultSetNumber
==
resultSetNumber
)
{
if
(
hasResultSet
&&
fetchResultSets
)
{
DBCResultSet
resultSet
=
dbcStatement
.
openResultSet
();
if
(
resultSet
==
null
)
{
// Kind of bug in the driver. It says it has resultset but returns null
break
;
}
else
{
DBDDataReceiver
dataReceiver
=
resultsConsumer
.
getDataReceiver
(
sqlQuery
,
resultSetNumber
);
if
(
dataReceiver
!=
null
)
{
hasResultSet
=
fetchQueryData
(
session
,
resultSet
,
curResult
,
dataReceiver
,
true
);
}
}
}
}
if
(!
hasResultSet
)
{
try
{
updateCount
=
dbcStatement
.
getUpdateRowCount
();
if
(
updateCount
>=
0
)
{
curResult
.
setUpdateCount
(
updateCount
);
statistics
.
addRowsUpdated
(
updateCount
);
}
}
catch
(
DBCException
e
)
{
// In some cases we can't read update count
// This is bad but we can live with it
// Just print a warning
log
.
warn
(
"Can't obtain update count"
,
e
);
}
}
if
(
hasResultSet
&&
fetchResultSets
)
{
resultSetNumber
++;
fetchResultSetNumber
=
resultSetNumber
;
}
if
(!
hasResultSet
&&
updateCount
<
0
)
{
// Nothing else to fetch
break
;
}
if
(
dataSource
.
getInfo
().
supportsMultipleResults
())
{
try
{
hasResultSet
=
dbcStatement
.
nextResults
();
}
catch
(
DBCException
e
)
{
log
.
error
(
e
);
// #2792: Check this twice. Some drivers (e.g. Sybase jConnect)
// throw error on n'th result fetch - but it still can keep fetching next results
hasResultSet
=
dbcStatement
.
nextResults
();
}
updateCount
=
hasResultSet
?
-
1
:
0
;
}
else
{
break
;
}
}
}
finally
{
SQLQuery
execStatement
=
sqlQuery
;
long
execStartTime
=
startTime
;
DBUtils
.
tryExecuteRecover
(
session
,
session
.
getDataSource
(),
param
->
{
try
{
curResult
.
addWarnings
(
dbcStatement
.
getStatementWarnings
()
);
executeStatement
(
session
,
execStatement
,
execStartTime
,
curResult
);
}
catch
(
Throwable
e
)
{
log
.
warn
(
"Can't read execution warnings"
,
e
);
throw
new
InvocationTargetException
(
e
);
}
//monitor.subTask("Close query");
if
(!
keepStatementOpen
())
{
closeStatement
();
}
}
});
}
catch
(
Throwable
ex
)
{
if
(!(
ex
instanceof
DBException
))
{
...
...
@@ -498,6 +417,101 @@ public class SQLQueryJob extends DataSourceJob
return
true
;
}
private
void
executeStatement
(
@NotNull
DBCSession
session
,
SQLQuery
sqlQuery
,
long
startTime
,
SQLQueryResult
curResult
)
throws
DBCException
{
DBCExecutionSource
source
=
new
AbstractExecutionSource
(
dataContainer
,
session
.
getExecutionContext
(),
partSite
.
getPart
(),
sqlQuery
);
final
DBCStatement
dbcStatement
=
DBUtils
.
makeStatement
(
source
,
session
,
DBCStatementType
.
SCRIPT
,
sqlQuery
,
rsOffset
,
rsMaxRows
);
curStatement
=
dbcStatement
;
int
statementTimeout
=
getDataSourceContainer
().
getPreferenceStore
().
getInt
(
DBeaverPreferences
.
STATEMENT_TIMEOUT
);
if
(
statementTimeout
>
0
)
{
try
{
dbcStatement
.
setStatementTimeout
(
statementTimeout
);
}
catch
(
Throwable
e
)
{
log
.
debug
(
"Can't set statement timeout:"
+
e
.
getMessage
());
}
}
// Execute statement
try
{
session
.
getProgressMonitor
().
subTask
(
"Execute query"
);
boolean
hasResultSet
=
dbcStatement
.
executeStatement
();
curResult
.
setHasResultSet
(
hasResultSet
);
statistics
.
addExecuteTime
(
System
.
currentTimeMillis
()
-
startTime
);
statistics
.
addStatementsCount
();
long
updateCount
=
-
1
;
while
(
hasResultSet
||
resultSetNumber
==
0
||
updateCount
>=
0
)
{
// Fetch data only if we have to fetch all results or if it is rs requested
if
(
fetchResultSetNumber
<
0
||
fetchResultSetNumber
==
resultSetNumber
)
{
if
(
hasResultSet
&&
fetchResultSets
)
{
DBCResultSet
resultSet
=
dbcStatement
.
openResultSet
();
if
(
resultSet
==
null
)
{
// Kind of bug in the driver. It says it has resultset but returns null
break
;
}
else
{
DBDDataReceiver
dataReceiver
=
resultsConsumer
.
getDataReceiver
(
sqlQuery
,
resultSetNumber
);
if
(
dataReceiver
!=
null
)
{
hasResultSet
=
fetchQueryData
(
session
,
resultSet
,
curResult
,
dataReceiver
,
true
);
}
}
}
}
if
(!
hasResultSet
)
{
try
{
updateCount
=
dbcStatement
.
getUpdateRowCount
();
if
(
updateCount
>=
0
)
{
curResult
.
setUpdateCount
(
updateCount
);
statistics
.
addRowsUpdated
(
updateCount
);
}
}
catch
(
DBCException
e
)
{
// In some cases we can't read update count
// This is bad but we can live with it
// Just print a warning
log
.
warn
(
"Can't obtain update count"
,
e
);
}
}
if
(
hasResultSet
&&
fetchResultSets
)
{
resultSetNumber
++;
fetchResultSetNumber
=
resultSetNumber
;
}
if
(!
hasResultSet
&&
updateCount
<
0
)
{
// Nothing else to fetch
break
;
}
if
(
session
.
getDataSource
().
getInfo
().
supportsMultipleResults
())
{
try
{
hasResultSet
=
dbcStatement
.
nextResults
();
}
catch
(
DBCException
e
)
{
log
.
error
(
e
);
// #2792: Check this twice. Some drivers (e.g. Sybase jConnect)
// throw error on n'th result fetch - but it still can keep fetching next results
hasResultSet
=
dbcStatement
.
nextResults
();
}
updateCount
=
hasResultSet
?
-
1
:
0
;
}
else
{
break
;
}
}
}
finally
{
try
{
curResult
.
addWarnings
(
dbcStatement
.
getStatementWarnings
());
}
catch
(
Throwable
e
)
{
log
.
warn
(
"Can't read execution warnings"
,
e
);
}
//monitor.subTask("Close query");
if
(!
keepStatementOpen
())
{
closeStatement
();
}
}
}
private
boolean
executeControlCommand
(
SQLControlCommand
command
)
throws
DBException
{
if
(
command
.
isEmptyCommand
())
{
return
true
;
...
...
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/ModelPreferences.java
浏览文件 @
be62fc82
...
...
@@ -113,7 +113,7 @@ public final class ModelPreferences
private
static
void
initializeDefaultPreferences
(
DBPPreferenceStore
store
)
{
// Common
PrefUtils
.
setDefaultPreferenceValue
(
store
,
QUERY_ROLLBACK_ON_ERROR
,
false
);
PrefUtils
.
setDefaultPreferenceValue
(
store
,
EXECUTE_RECOVER_ENABLED
,
tru
e
);
PrefUtils
.
setDefaultPreferenceValue
(
store
,
EXECUTE_RECOVER_ENABLED
,
fals
e
);
PrefUtils
.
setDefaultPreferenceValue
(
store
,
EXECUTE_RECOVER_RETRY_COUNT
,
1
);
// SQL execution
...
...
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBUtils.java
浏览文件 @
be62fc82
...
...
@@ -29,7 +29,8 @@ import org.jkiss.dbeaver.model.exec.*;
import
org.jkiss.dbeaver.model.impl.data.DefaultValueHandler
;
import
org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect
;
import
org.jkiss.dbeaver.model.runtime.DBRProgressMonitor
;
import
org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress
;
import
org.jkiss.dbeaver.model.runtime.DBRRunnableParametrized
;
import
org.jkiss.dbeaver.model.runtime.VoidProgressMonitor
;
import
org.jkiss.dbeaver.model.sql.*
;
import
org.jkiss.dbeaver.model.struct.*
;
import
org.jkiss.dbeaver.model.struct.rdb.*
;
...
...
@@ -1468,7 +1469,11 @@ public final class DBUtils {
return
list
;
}
public
static
boolean
tryExecuteRecover
(
@NotNull
DBRProgressMonitor
monitor
,
@NotNull
DBPDataSource
dataSource
,
@NotNull
DBRRunnableWithProgress
runnable
)
throws
DBException
{
/**
* @param param DBRProgressProgress monitor or DBCSession
*
*/
public
static
<
T
>
boolean
tryExecuteRecover
(
@NotNull
T
param
,
@NotNull
DBPDataSource
dataSource
,
@NotNull
DBRRunnableParametrized
<
T
>
runnable
)
throws
DBException
{
int
tryCount
=
1
;
boolean
recoverEnabled
=
dataSource
.
getContainer
().
getPreferenceStore
().
getBoolean
(
ModelPreferences
.
EXECUTE_RECOVER_ENABLED
);
if
(
recoverEnabled
)
{
...
...
@@ -1477,7 +1482,7 @@ public final class DBUtils {
Throwable
lastError
=
null
;
for
(
int
i
=
0
;
i
<
tryCount
;
i
++)
{
try
{
runnable
.
run
(
monitor
);
runnable
.
run
(
param
);
lastError
=
null
;
break
;
}
catch
(
InvocationTargetException
e
)
{
...
...
@@ -1487,6 +1492,14 @@ public final class DBUtils {
break
;
}
log
.
debug
(
"Invalidate datasource '"
+
dataSource
.
getContainer
().
getName
()
+
"' connections..."
);
DBRProgressMonitor
monitor
;
if
(
param
instanceof
DBRProgressMonitor
)
{
monitor
=
(
DBRProgressMonitor
)
param
;
}
else
if
(
param
instanceof
DBCSession
)
{
monitor
=
((
DBCSession
)
param
).
getProgressMonitor
();
}
else
{
monitor
=
new
VoidProgressMonitor
();
}
InvalidateJob
.
invalidateDataSource
(
monitor
,
dataSource
,
false
);
if
(
i
<
tryCount
-
1
)
{
log
.
error
(
"Operation failed. Retry count remains = "
+
(
tryCount
-
i
-
1
),
lastError
);
...
...
@@ -1501,4 +1514,5 @@ public final class DBUtils {
}
return
true
;
}
}
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/DBRRunnableParametrized.java
0 → 100644
浏览文件 @
be62fc82
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.jkiss.dbeaver.model.runtime
;
import
java.lang.reflect.InvocationTargetException
;
/**
* Runnable with parameter
*/
public
interface
DBRRunnableParametrized
<
T
>
{
void
run
(
T
param
)
throws
InvocationTargetException
,
InterruptedException
;
}
\ No newline at end of file
plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/runtime/DBRRunnableWithProgress.java
浏览文件 @
be62fc82
...
...
@@ -17,15 +17,11 @@
package
org.jkiss.dbeaver.model.runtime
;
import
java.lang.reflect.InvocationTargetException
;
/**
* Database progress monitor.
* Similar to IProgressMonitor but with DBP specific features
*/
public
interface
DBRRunnableWithProgress
{
public
interface
DBRRunnableWithProgress
extends
DBRRunnableParametrized
<
DBRProgressMonitor
>
{
void
run
(
DBRProgressMonitor
monitor
)
throws
InvocationTargetException
,
InterruptedException
;
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录