Layers, design and transactionality.

Hello all!

I am fairly new to Spring Boot and coding in general.

I took it upon me to build a simple browser game where the player chooses an action and gains resources over time. I am currently finishing the prototype and I am being slowly introduced to all of the concepts behind the actual coding, but also when it comes to layering and design choices as well.

On to my dilemma.

So far I have several @ Transactional annotations inside the service layer whenever I interact with the repository layer in order to ensure that no two methods make changes to the DB - throwing any calculations made go haywire. Not sure if this is a common or best practice but it was a semi-conscious decision that I made during the early stages of development.

Now I am at a point where I have two identically named methods inside the service layer:

  • calculateProgress(UUID playerId) - it searches the db for a PlayerCharacter instance using the playerId field and then does some calculations.
  • calculateProgress(PlayerCharacter character) - it already gets a PlayerCharacter instance and does the calculations.

In fact, the first one calls the second one inside its body. The reason for this is that there is a scheduler that calculates the progress in regular intervals. And that scheduler only knows the PlayerCharacter's playerId and not any other information for that PlayerCharacter. So my initial thought was to have it call calculateProgress(UUID playerId) which in turn calls calculateProgress(PlayerCharacter character) to make the calculations etc etc.

I was not thinking much about it when I first did this but now I am realising that having two methods with the exact same name (and different arguments) might be ugly/not a good practice for the readability and maintainability of my code.

Now I am thinking: I could have the scheduler method call a new service method that returns a PlayerCharacter instance if I give it the playerId, and then call calculateProgress(PlayerCharacter character).

That would mean though that I need to have the scheduler method have a @ Transactional annotation to avoid the race conditions that I mentioned earlier. That would in turn break my initial decision of having Transactional annotations in the service layer only and also move db integrity from the service layer to the scheduler layer.

So I am thinking again and I pose the same question to anyone who might read this: Is it a common/good/best practice to have transactionality into the scheduler layer as well as the service layer or is there another option for my case?

Thanks in advance for anyone providing any feedback to my conundrum!

TL;DR: Have Transactional annotated methods inside the scheduling layer as an exception OR keep them strictly inside the service layer instead? Is it a good/common practice to do that split?

reddit.com
u/ZeGuru101 — 1 day ago

My casual mage outfit

Any feedback is greatly appreciated.

Bonus points if you have the "Professor" title as well!

Item list:

Dazzling Spectacles

Valorous Frostfire Shoulderpads

Greatcloak of the Dark Pantheon

Azure Silk Vest

Marquis Lace Cuffs

Aaluneth

Hidden Shirt

Hidden Gloves

Padded Belt

Tuxedo Pants

Cloudburst Slippers

Hidden Tabard

u/ZeGuru101 — 3 months ago