背景
在我的数据库中,我有一些唯一性约束。如果数据破坏了其中一种情况,我会收到一条错误消息,例如Violation of UNIQUE KEY constraint
.
我tryCatch
在我的代码中使用,以捕获此错误并向用户返回有意义的消息。到目前为止,一切都很好。
但是,如果我在捕获此错误后尝试在服务器上运行任何新事务,我会收到另一条错误消息,说我Cannot begin a nested transaction.
我的发现
我追查了错误,我发现当dbRollback
被调用(显式或在 内withTransaction
)时,不能再提交任何新dbBegin
的(通过dbWriteTable
和朋友显式或隐式地)。
我需要摆脱困境的是运行一个dbCommit
,被允许运行另一个dbBegin
。
查看代码,dbCommit
我dbRollback
发现在前一种情况下
setAutoCommit
设置为 true,这dbBegin
表明我们没有嵌套事务。情况并非如此dbRollback
:
getMethod("dbCommit", "SQLServerConnection")
# Method Definition:
#
# function (conn, ...)
# {
# rJava::.jcall(conn@jc, "V", "commit")
# rJava::.jcall(conn@jc, "V", "setAutoCommit", TRUE)
# TRUE
# }
# <environment: namespace:RSQLServer>
getMethod("dbRollback", "SQLServerConnection")
# Method Definition:
#
# function (conn, ...)
# {
# rJava::.jcall(conn@jc, "V", "rollback")
# TRUE
# }
# <environment: namespace:RSQLServer>
问题
所以我的问题是:这是假定的行为吗?也就是说,我是想dbCommit
在操作回滚后运行手册,还是这是一个错误?
代码
library(DBI)
library(RSQLServer)
db <- dbConnect(...)
dbBegin(db)
dbCommit(db)
dbBegin(db) # works
dbRollback(db)
dbBegin(db) # does not work
dbCommit(db) # my workaround
dbBegin(db) # works again