Self-contained SQL transactions
Given that transactions are implemented, this function
allows you to pass in code that is run in a transaction.
The default method of dbWithTransaction()
calls dbBegin()
before executing the code,
and dbCommit()
after successful completion,
or dbRollback()
in case of an error.
The advantage is
that you don't have to remember to do dbBegin()
and dbCommit()
or
dbRollback()
– that is all taken care of.
The special function dbBreak()
allows an early exit with rollback,
it can be called only inside dbWithTransaction()
.
dbWithTransaction(conn, code, ...) dbBreak()
conn |
A DBIConnection object, as returned by
|
code |
An arbitrary block of R code. |
... |
Other parameters passed on to methods. |
DBI implements dbWithTransaction()
, backends should need to override this
generic only if they implement specialized handling.
dbWithTransaction()
returns the value of the executed code.
Failure to initiate the transaction
(e.g., if the connection is closed
or invalid
of if dbBegin()
has been called already)
gives an error.
dbWithTransaction()
initiates a transaction with dbBegin()
, executes
the code given in the code
argument, and commits the transaction with
dbCommit()
.
If the code raises an error, the transaction is instead aborted with
dbRollback()
, and the error is propagated.
If the code calls dbBreak()
, execution of the code stops and the
transaction is silently aborted.
All side effects caused by the code
(such as the creation of new variables)
propagate to the calling environment.
con <- dbConnect(RSQLite::SQLite(), ":memory:") dbWriteTable(con, "cash", data.frame(amount = 100)) dbWriteTable(con, "account", data.frame(amount = 2000)) # All operations are carried out as logical unit: dbWithTransaction( con, { withdrawal <- 300 dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) } ) # The code is executed as if in the curent environment: withdrawal # The changes are committed to the database after successful execution: dbReadTable(con, "cash") dbReadTable(con, "account") # Rolling back with dbBreak(): dbWithTransaction( con, { withdrawal <- 5000 dbExecute(con, "UPDATE cash SET amount = amount + ?", list(withdrawal)) dbExecute(con, "UPDATE account SET amount = amount - ?", list(withdrawal)) if (dbReadTable(con, "account")$amount < 0) { dbBreak() } } ) # These changes were not committed to the database: dbReadTable(con, "cash") dbReadTable(con, "account") dbDisconnect(con)
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.