Skip to content

Commit 96f97a6

Browse files
author
Philipp Korber
committed
Fixes sfackler#371 by not reusing the same savepoint name.
Rolling back to a savepoint doesn't release it so, reusing the same name in nested transaction means inner transactions only roll back to the most transaction/last savepoint. If the outer most transaction commits but did multiple consecutive rollbacks in the nested transactions this did cause an unexpected state in the database before the fix.
1 parent a7db658 commit 96f97a6

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

postgres/src/transaction.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl<'conn> Transaction<'conn> {
244244
///
245245
/// Panics if there is an active nested transaction.
246246
pub fn transaction<'a>(&'a self) -> Result<Transaction<'a>> {
247-
self.savepoint("sp")
247+
self.savepoint(format!("sp_{}", self.depth()))
248248
}
249249

250250
/// Like `Connection::transaction`, but creates a nested transaction via
@@ -253,7 +253,14 @@ impl<'conn> Transaction<'conn> {
253253
/// # Panics
254254
///
255255
/// Panics if there is an active nested transaction.
256-
pub fn savepoint<'a>(&'a self, name: &str) -> Result<Transaction<'a>> {
256+
#[inline]
257+
pub fn savepoint<'a, I>(&'a self, name: I) -> Result<Transaction<'a>>
258+
where I: Into<String>
259+
{
260+
self._savepoint(name.into())
261+
}
262+
263+
fn _savepoint<'a>(&'a self, name: String) -> Result<Transaction<'a>> {
257264
let mut conn = self.conn.0.borrow_mut();
258265
check_desync!(conn);
259266
assert!(
@@ -265,7 +272,7 @@ impl<'conn> Transaction<'conn> {
265272
Ok(Transaction {
266273
conn: self.conn,
267274
depth: self.depth + 1,
268-
savepoint_name: Some(name.to_owned()),
275+
savepoint_name: Some(name),
269276
commit: Cell::new(false),
270277
finished: false,
271278
})

0 commit comments

Comments
 (0)