4343
4444import com .cloud .utils .db .GenericDaoBase ;
4545import com .cloud .utils .db .TransactionLegacy ;
46+ import com .cloud .utils .exception .CloudRuntimeException ;
4647
4748// Kept outside com.cloud.utils.db because framework/db excludes that package's tests from the build.
4849@ RunWith (MockitoJUnitRunner .class )
@@ -142,6 +143,19 @@ public void persistOutsideATransactionCommitsWithoutASavepoint() throws SQLExcep
142143 Assert .assertFalse (txn .dbTxnStarted ());
143144 }
144145
146+ @ Test
147+ public void persistInsideCallerTransactionLeavesItIntactWhenTheSavepointCannotBeTaken () throws SQLException {
148+ Mockito .when (conn .setSavepoint ()).thenThrow (new SQLException ("Connection lost" ));
149+ txn .start ();
150+
151+ Assert .assertThrows (CloudRuntimeException .class , () -> dao .persist (new PersistTestVO ()));
152+
153+ Mockito .verify (conn , Mockito .never ()).rollback ();
154+ Assert .assertTrue (txn .dbTxnStarted ());
155+ Assert .assertTrue (txn .commit ());
156+ Mockito .verify (conn ).commit ();
157+ }
158+
145159 @ Test
146160 public void failedSetSavepointLeavesTheCallerTransactionIntact () throws SQLException {
147161 Mockito .when (conn .setSavepoint ()).thenThrow (new SQLException ("Connection lost" ));
@@ -168,6 +182,20 @@ public void failedReleaseSavepointLeavesItAvailableForRollback() throws SQLExcep
168182 Mockito .verify (conn ).commit ();
169183 }
170184
185+ @ Test
186+ public void namedSavepointRollsBackOnlyItsOwnLevel () throws SQLException {
187+ Mockito .when (conn .setSavepoint ("persist" )).thenReturn (savepoint );
188+ txn .start ();
189+ final Savepoint sp = txn .setSavepoint ("persist" );
190+
191+ txn .rollback (sp );
192+
193+ Mockito .verify (conn ).rollback (savepoint );
194+ Mockito .verify (conn , Mockito .never ()).rollback ();
195+ Assert .assertTrue (txn .commit ());
196+ Mockito .verify (conn ).commit ();
197+ }
198+
171199 @ Entity
172200 @ Table (name = "persist_test" )
173201 public static class PersistTestVO {
0 commit comments