Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring: how to execute `@Sql` within the transaction of test method?

I need the following logic:
1. Test method starts
2. Transaction opens
3. Prepare SQL file is executed
4. Test method is processed
5. Transaction rollbacks

My test class is annotated with

@SpringBootTest
@Transactional
@Rollback(true)

I tried to use @org.springframework.test.context.jdbc.Sql before test method but it doesn't work - looks like it opens a transaction, executes SQL, closes transaction (reverts it?) and after that starts test. A test doesn't see changes from SQL file

My question is: how to execute @org.springframework.test.context.jdbc.Sql within the transaction of test method? Any other way to solve this problem?

like image 448
fedor.belov Avatar asked Apr 13 '18 13:04

fedor.belov


People also ask

Can we use JdbcTemplate with @transactional?

It loops through the list of people and, for each person, inserts that person into the BOOKINGS table by using the JdbcTemplate . This method is tagged with @Transactional , meaning that any failure causes the entire operation to roll back to its previous state and to re-throw the original exception.

How do I test a rollback transaction?

Annotation Type Rollback@Rollback is a test annotation that is used to indicate whether a test-managed transaction should be rolled back after the test method has completed. Consult the class-level Javadoc for TransactionalTestExecutionListener for an explanation of test-managed transactions.

How do Spring transactions work internally?

Transactions and Proxies. At a high level, Spring creates proxies for all the classes annotated with @Transactional, either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the running method, mainly for starting and committing the transaction.

What does @transactional do in Spring?

The generated proxy object is supplied with a TransactionInterceptor, which is created by Spring. So when the @Transactional method is called from client code, the TransactionInterceptor gets invoked first from the proxy object, which begins the transaction and eventually invokes the method on the target bean.


1 Answers

You should have a look at the config property of the @Sql annotation, there it is possible to specify the TransactionMode to be used.

So for instance the following scripts are executed in a separate transaction ahead of entering the test method:

@Sql(
  scripts = {"classpath:file1.sql", "classpath:file2.sql"},
  config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
@Test
public void foo() { ... }
like image 94
johanwannheden Avatar answered Sep 25 '22 00:09

johanwannheden