1

背景

在我的数据库中,我有一些唯一性约束。如果数据破坏了其中一种情况,我会收到一条错误消息,例如Violation of UNIQUE KEY constraint.

tryCatch在我的代码中使用,以捕获此错误并向用户返回有意义的消息。到目前为止,一切都很好。

但是,如果我在捕获此错误后尝试在服务器上运行任何新事务,我会收到另一条错误消息,说我Cannot begin a nested transaction.

我的发现

我追查了错误,我发现当dbRollback被调用(显式或在 内withTransaction)时,不能再提交任何新dbBegin的(通过dbWriteTable和朋友显式或隐式地)。

我需要摆脱困境的是运行一个dbCommit,被允许运行另一个dbBegin

查看代码,dbCommitdbRollback发现在前一种情况下 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
4

0 回答 0