Point system design in Spring

I already have a lot of existing data in my database and you want to develop a point mechanism that calculates the score for each user based on what actions they perform.

I implement this functionality in a pluggable manner so that it is independent of the core logic and relies on Spring events dispatched around once the object is modified.

The problem is what to do with existing data. I do not want to start collecting points from now on, but rather all the data so far.

What is the most practical way to do this? Should I design my plugins in such a way as to provide an index () method that will force my system to retrieve each individual object from the database, send an EntityDirtyEvent to run the point plugins for each of them, and then update this so that the points are kept next to every object. This can lead to a lot of overhead, right?

The simplest task would be to create a complex stored procedure, and then make the index () call this stored procedure. This, however, seems bad to me. Since I still have to write logic to calculate points in java, why is this again in SQL? In addition, I am not a fan of dividing business logic into different layers at all.

Has anyone done this before? Please, help.

+6
source share
5 answers

First, let's distinguish between an implementation strategy and a business rule.

Since you already have data, consider getting results directly from the data. This forms a data domain model. Create a data model to store all your data. Then create a set of queries, views, and stored procedures to access and update data.

Once you have these views, use a data access library such as the Spring JDBC Template to get this data and present it in Java objects (lists, maps, faces, point tables, etc.).

What you have completed so far has not changed much, regardless of what happens in the upper layers of the system. This is called Model.

Then create a rule base or logical implementation that determines under which inputs, user actions, data conditions or for all other conditions what data is needed. In a mathematical sense, it looks like a matrix. In terms of programming, it will be a set of logical statements. If this and this, and this is true, then get this data, still get this data, etc. This includes the logic of your system. Therefore, it is called the “Controller”.

Do not move this logic to queries / stored procedure / views.

Then, finally, create an interface or console for this. In the simplest case, create a console input system that accepts ... and displays a result set. This is your "view" of the system.

Ultimately, you can create a view in a web application. The above command line representation may be viable as a Restful API server.

+4
source

I think there is one problem here: I understand the huge data in the database, so the idea of ​​creating only one mechanism for calculating a point system cannot be the best approach.

In fact, if you do not want to start collecting points, but include all the data, you must process and calculate the information that you have now. Yes, this can lead to overhead on the first start, but as you said, you need this data.

On the other hand, you can turn on another mechanism that participates in changes to the entity and starts another process that can calculate the new directional difference applicable to this particular modification.

Thus, you can use one service responsible for calculating the guidance system, one for one object and another, it may take longer to complete, able to calculate global points. Even if you do not need to count in real time, you can create a scheduled task responsible for its launch.

Finally, I know that this is not a good approach for separating business logic in two layers (Db + Java), but sometimes it is necessary, for example, if you need to quickly respond to a request that ultimately works with many registries . I found some cases where there is no other option than adding business logic to the database (like stored procedures, etc.) to manage a lot of data and return the final result to the browser client (for example: the calculation process in a certain time).

+2
source

You are trying to perform a "boot". The approach you choose should depend on how complex point calculations are. If stored procedures or simple update statements are the easiest solution, do it.

If the calculations are complex, write a batch job that loads your existing data, probably puts it first in the first place, and fires events corresponding to that data as if they had just happened. The code associated with the event must be exactly the same code that will deal with the future event, so you do not have to write any additional code other than the batch tasks themselves.

Since you are going to run this thing only once, go to the simplest solution, even if it is fast and dirty.

+2
source

You seem to be heading in the right direction. You know that you want your “points” to be separated from the main application. Since it is assumed that you are already using sleep mode (by tag!), You can use the sleep mode event system (see section 14.2 here ). Depending on the size / complexity of your system, you can connect your point calculations here (if it is not a large / complex system), or you can publish your own event, which will be picked up by any software.

The point in any design approach is that no one knows or cares about your point calculations. If you, as I assume, are trying to create a fairly general plug-in mechanism, then you publish your own events on this system from this anchor point. Then, if you do not have plugins for this installation / installation, no one receives / processes events. If you have several plug-ins on another installation / installation, each of them can decide what processing they should perform based on the received event. In the case of the "point plugin", it calculates the point value and saves it. No saved proc is required ....

+2
source

There are two different ways. One thing you already know is that - poll the database for the modified data. In this case, you get to the database when there can be no changes, and this can slow down the process.

Second approach. Whenever a change occurs in the database, the database fires an event. This can be used with CDC (Change Data Capture). This minimizes overhead.

You can find additional options in Spring Integration

+1
source

Source: https://habr.com/ru/post/921502/


All Articles