Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing different Spring Repositories to use the same transaction

I'm working on a project where I want to use a very specific transaction propagation strategy. The database has two sets of tables, active and archive. Each set of tables is implemented with its own Entities and Interfaces that extend CrudRepository<T, ID>. The goal is to have a set of entities inserted into the active tables and to have all the data in the active tables inserted into the archive tables in a single transaction. The entities in the tables are not the same, and will have different table structures.

Given two separate repositories similar to the form

public interface FooRepository extends CrudRepository<Foo, Integer>
public interface FooArchiveRepository extends CrudRepository<FooArchive, Integer>

and an implementation similar to

@Autowired FooRepository fooRepo;
@Autowired FooArchiveRepository fooArchiveRepo;
@Autowired BarService barService;
List<Foo> newData = barService.doThing();
fooRepo.saveAll(newData);
// fooData is a list of FooArchive from earlier
fooArchiveRepo.saveAll(fooData);

The goal is to have fooRepo.saveAll(newData) and fooArchiveRepo.saveAll(fooData) be guaranteed to execute in a single database transaction. Spring's default transaction propagation of Required has different Transactional methods execute in the same physical transaction - does that apply to all Transactional methods within the Application Context, or only on a per-entity basis?

like image 331
Leo Avatar asked Oct 02 '18 16:10

Leo


People also ask

What is transaction synchronization Spring?

Spring provides support for synchronizing resources with transactions since the earliest versions. We often use it to synchronize transactions managed by multiple transaction managers. For example, we can synchronize a JMS commit with a JDBC commit.

Does @transactional lock table Spring?

"@Transactional" as itself on any isolation level doesn't enabling any locking. To achieve locking behaviour you should use "@Lock" annotation or use " for update" in your query.

Can we have multiple repository in Spring boot?

You can only have one repository per entity... however, you can have multiple entities per table; thus, having multiple repositories per table.

Does Spring support nested transactions?

Nested transactions in Spring are just JDBC / database savepoints. If you don't know what a savepoint is, have a look at this tutorial, for example. Note that savepoint support is dependent on your JDBC driver/database.


1 Answers

wrap the save calls into a new method and annotate the method with @Transactional

@Transactional
public void saveAll(){
  fooRepo.saveAll(newData);
  // fooData is a list of FooArchive from earlier
  fooArchiveRepo.saveAll(fooData);
}

by default (PROPAGATION_REQUIRED) it will execute the inner transactions into the same transaction. Please see https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/images/tx_prop_required.png

like image 87
Adina Rolea Avatar answered Oct 08 '22 12:10

Adina Rolea