Prevent inner transaction from rolling back outer transaction

Christopher

I have a somewhat complex transaction which does or does not create many different types of entities. Should it fail to create one of those entities due to a validation error, I'd like to simply catch the ConstraintValidationError and move on (allowing any other entities created in the same transaction to save successfully).

I can do this successfully but the validation error still marks my whole transaction for rollback, which I do not want.

I tried changing the single validating method which causes the ConstraintValidationError to have a:

@Transactional(propagation = Propagation.NOT_SUPPORTED)

to force a new transaction, thinking it would mark only that new, inner transaction for rollback, but that doesn't seem to be the case.

The calling class is marked with a:

@Transactional(noRollbackFor=ConstraintViolationException.class)

but this doesn't help if the ConstraintViolationException is in the called method and I do not wish to add it to the called method.

What's the proper way to do something like this?

(Let me know if code is required -- the example is somewhat complex.)

EDIT (5/26/14):

When I try

progration = Propagation.REQUIRES_NEW

I see no change in the result. This particular log is from a test purposefully trying to save a 'department' entity object with a null description, which would be invalid:

11:46:43.599 [main] DEBUG org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'DefaultCourseManager.saveDepartment' with attribute: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT; ''
11:46:43.599 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'transactionManager'
11:46:43.599 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@3a90c13c] for JPA transaction
11:46:43.599 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Suspending current transaction, creating new transaction with name [edu.ucdavis.dss.dw.site.DefaultCourseManager.saveDepartment]
11:46:43.600 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@67b355c8] for JPA transaction
11:46:43.600 [main] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - begin
11:46:43.600 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Obtaining JDBC connection
11:46:43.601 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Obtained JDBC connection
11:46:43.601 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - initial autocommit status: true
11:46:43.601 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - disabling autocommit
11:46:43.601 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@388623ad]
11:46:43.601 [main] DEBUG org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource - Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
11:46:43.602 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'transactionManager'
11:46:43.602 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@67b355c8] for JPA transaction
11:46:43.602 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Participating in existing transaction
11:46:43.606 [main] DEBUG org.hibernate.SQL - select KeyValue from SurrogateKeys where TableName = 'Departments' for update
11:46:43.608 [main] DEBUG org.hibernate.SQL - insert into SurrogateKeys(TableName, KeyValue) values('Departments', ?)
11:46:43.610 [main] DEBUG org.hibernate.SQL - update SurrogateKeys set KeyValue = ? where KeyValue = ? and TableName = 'Departments'
11:46:43.612 [main] DEBUG org.hibernate.SQL - select KeyValue from SurrogateKeys where TableName = 'Departments' for update
11:46:43.612 [main] DEBUG org.hibernate.SQL - update SurrogateKeys set KeyValue = ? where KeyValue = ? and TableName = 'Departments'
11:46:43.613 [main] DEBUG org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: 1, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator
11:46:43.613 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction commit
11:46:43.613 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@67b355c8]
11:46:43.613 [main] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - committing
11:46:43.613 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
11:46:43.614 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Dirty checking collections
11:46:43.614 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 1 insertions, 0 updates, 0 deletions to 1 objects
11:46:43.614 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
11:46:43.614 [main] DEBUG org.hibernate.internal.util.EntityPrinter - Listing entities:
11:46:43.614 [main] DEBUG org.hibernate.internal.util.EntityPrinter - edu.ucdavis.dss.dw.entities.Department{courses=null, code=null, name=null, id=1}
11:46:43.620 [main] DEBUG org.hibernate.validator.resourceloading.PlatformResourceBundleLocator - ValidationMessages not found.
11:46:43.624 [main] DEBUG org.hibernate.validator.resourceloading.PlatformResourceBundleLocator - org.hibernate.validator.ValidationMessages found.
11:46:43.637 [main] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - rolling back
11:46:43.638 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - rolled JDBC Connection
11:46:43.638 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - re-enabling autocommit
11:46:43.639 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@67b355c8] after transaction
11:46:43.640 [main] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
11:46:43.648 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Releasing JDBC connection
11:46:43.649 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Released JDBC connection
11:46:43.649 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Resuming suspended transaction after completion of inner transaction
11:46:43.651 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction rollback
11:46:43.651 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@3a90c13c]
11:46:43.651 [main] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - rolling back
11:46:43.651 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - rolled JDBC Connection
11:46:43.651 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - re-enabling autocommit
11:46:43.652 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@3a90c13c] after transaction
11:46:43.652 [main] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
11:46:43.652 [main] DEBUG org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl - HHH000420: Closing un-released batch
11:46:43.652 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Releasing JDBC connection
11:46:43.653 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Released JDBC connection
11:46:43.655 [main] DEBUG com.github.springtestdbunit.DbUnitTestExecutionListener - Skipping @DatabaseTest expectation due to test exception class org.springframework.transaction.TransactionSystemException
11:46:43.656 [main] DEBUG org.dbunit.database.DatabaseDataSourceConnection - close() - start
11:46:43.657 [main] DEBUG org.springframework.test.context.support.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@1da2cb77 testClass = BannerManagerTestCase, testInstance = edu.ucdavis.dss.dw.site.BannerManagerTestCase@48f278eb, testMethod = testCatchesNullDepartment@BannerManagerTestCase, testException = org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction, mergedContextConfiguration = [MergedContextConfiguration@2f217633 testClass = BannerManagerTestCase, locations = '{}', classes = '{class edu.ucdavis.dss.dw.config.TestContextConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false].
11:46:43.675 [main] DEBUG org.springframework.test.context.support.DirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@1da2cb77 testClass = BannerManagerTestCase, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2f217633 testClass = BannerManagerTestCase, locations = '{}', classes = '{class edu.ucdavis.dss.dw.config.TestContextConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false].
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 7.299 sec <<< FAILURE!

Results :

Tests in error: 
  testCatchesNullDepartment(edu.ucdavis.dss.dw.site.BannerManagerTestCase): Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction

If I'm not sure if I'm reading that correctly -- I see the null-valued department entity and then the information that it is rolling back but one would think it would indicate somewhere as to why it decided to rollback.

kostja

You can run the problematic method in a new transaction. Instead of @Transactional(propagation = Propagation.NOT_SUPPORTED), you should use Propagation.REQUIRES_NEW:

@Transactional(propagation = Propagation.REQUIRES_NEW)

to force the creation of a new transaction. NOT_SUPPORTED does not lead to the creation of a new transaction, it only suspends the current one.

Wrap the call to the method in a try/catch block. I am not sure what Exception you are going to get in a spring environment. In Java EE, it would be EJBException.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Rails transaction not rolling back

From Dev

PetaPoco transaction not rolling back

From Dev

Cordova SQLite transaction not rolling back

From Dev

Prevent IndexedDB request error from cancelling the transaction

From Dev

Laravel DB::transaction not rolling back on exception

From Dev

ActiveRecord transaction is not rolling back whole transaction

From Dev

Rolling back transaction with Oracle OCCI

From Dev

about nested transaction, the outer scope gives me "The Transaction has been aborted" exception, but the inner scope returns succesfully

From Dev

Exceptions when rolling back a transaction - connection already closed?

From Dev

How to prevent NServiceBus from rolling back the transaction or parts of it?

From Dev

TSQL: Prevent trigger suppressing error but rolling back transaction

From Dev

Rolling back a transaction in apache chemistry cmis

From Dev

SQL Server - Rolling back particular transaction only at a later date

From Dev

Spring transactions: inner transaction changes are "rolled back" by outer transaction (or maybe jpa misuse)

From Dev

How to prevent a specific INSERT statement from rolling back in a transaction

From Dev

Peewee: Outer transaction does not roll back inner transaction (savepoints)

From Dev

Kafka Transaction Manager sends to Kafka Broker despite transaction rolling back

From Dev

Changes from an inner transaction are not visible from outer

From Dev

Prevent inner transaction from rolling back outer transaction

From Dev

Transaction in stored procedure not rolling back

From Dev

Rolling back Transaction Doesn't Work with TpFIB Components

From Dev

How to prevent NServiceBus from rolling back the transaction or parts of it?

From Dev

Rolling back transaction scope C#

From Dev

Rolling back a transaction in apache chemistry cmis

From Dev

MySQL transaction not rolling back on error

From Dev

Jms-message-driven channel adaper not rolling back the transaction

From Dev

How to prevent a specific INSERT statement from rolling back in a transaction

From Dev

Why is my MSDTC transaction not correctly rolling back on my localhost environment?

From Dev

What is a good way of rolling back a transaction in Postgres

Related Related

  1. 1

    Rails transaction not rolling back

  2. 2

    PetaPoco transaction not rolling back

  3. 3

    Cordova SQLite transaction not rolling back

  4. 4

    Prevent IndexedDB request error from cancelling the transaction

  5. 5

    Laravel DB::transaction not rolling back on exception

  6. 6

    ActiveRecord transaction is not rolling back whole transaction

  7. 7

    Rolling back transaction with Oracle OCCI

  8. 8

    about nested transaction, the outer scope gives me "The Transaction has been aborted" exception, but the inner scope returns succesfully

  9. 9

    Exceptions when rolling back a transaction - connection already closed?

  10. 10

    How to prevent NServiceBus from rolling back the transaction or parts of it?

  11. 11

    TSQL: Prevent trigger suppressing error but rolling back transaction

  12. 12

    Rolling back a transaction in apache chemistry cmis

  13. 13

    SQL Server - Rolling back particular transaction only at a later date

  14. 14

    Spring transactions: inner transaction changes are "rolled back" by outer transaction (or maybe jpa misuse)

  15. 15

    How to prevent a specific INSERT statement from rolling back in a transaction

  16. 16

    Peewee: Outer transaction does not roll back inner transaction (savepoints)

  17. 17

    Kafka Transaction Manager sends to Kafka Broker despite transaction rolling back

  18. 18

    Changes from an inner transaction are not visible from outer

  19. 19

    Prevent inner transaction from rolling back outer transaction

  20. 20

    Transaction in stored procedure not rolling back

  21. 21

    Rolling back Transaction Doesn't Work with TpFIB Components

  22. 22

    How to prevent NServiceBus from rolling back the transaction or parts of it?

  23. 23

    Rolling back transaction scope C#

  24. 24

    Rolling back a transaction in apache chemistry cmis

  25. 25

    MySQL transaction not rolling back on error

  26. 26

    Jms-message-driven channel adaper not rolling back the transaction

  27. 27

    How to prevent a specific INSERT statement from rolling back in a transaction

  28. 28

    Why is my MSDTC transaction not correctly rolling back on my localhost environment?

  29. 29

    What is a good way of rolling back a transaction in Postgres

HotTag

Archive