背景
在我的数据库中,我有一些唯一性限制。如果数据中断了其中一个条件,我会收到类似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