Annual Outsourcing Conference & Innovation, Technology and Sourcing Awards

DataStork in Top Three for the Startup of the Year Award

On the 8th of June Varna hosted the fifth edition of the Annual Outsourcing Conference – an event celebrating the innovation and digitalization in the outsourcing business. Organized by the Bulgarian Outsourcing Association (BOA) the conference was a full day of discussion panels led by some of the sector’s leaders and was an outstanding opportunity to share experience and ideas with the industry’s best.

The event culminated with the ceremony for the Innovation, Technology and Sourcing Awards 2018. The awards were given out for a third year, honoring the efforts of local government, investors and companies for leading best practice and business excellence and creating a favorable business environment for the growth of the sourcing and technology industry in Bulgaria. DataStork participated in the Young Company/Startup of the Year category and was proud to be awarded third place, following the winner Cargotec and Red Fire Games and Sandvik who shared the second place with the same number of points. DataStork’s own CEO, Doichin Yordanov and HR Manager, Hristina Andonova were there to attend the conference and receive the award.

The Young Company/Startup of the Year Award is for companies that have been operating on the market for up to 3 years at the moment of application. A panel of industry experts evaluated applicants in four areas – Team and Business Results, Market, Growth or Potential for Growth and Innovation/Disruption, consistent with the long-term objectives of the company. DataStork was recognized for its unique software development process which guarantees 100% success rate, the R&D engineers and managers team where experienced staff boosts young talents through close mentorship and internal trainings, and the company’s policy on empowering its employees to drive all aspects of its development. This is the first time we have applied for the category and we’re honored to have come out in the top three!

A huge thank you to the Bulgarian Outsourcing Association. We look forward to seeing you in 2019 when we have our sights set on first place!


Spring Transactional Proxies

Here we will discuss the Spring wonderland of proxies and database transactions.

Often we need to create Spring services that work with database transactions. First we define an interface, for example let’s take a simple UsersService like this:

public interface UsersService {
  ...

  void cleanupUsers();

  ...
}

Then implement with the known @Transactional annotation:

@Service
public class UsersServiceImpl implements UsersService {
  ...

  @Transactional
  @Overwrite
  public void cleanupUsers() {
    callDbOperationsPart1();
    callDbOperationsPart2();
    callDbOperationsPart3();
    callDbOperationsPart4();
  }

  ...
}

The @Transactional annotation results in the above relational DB operations done in one single transaction. If even a single operation fails, all will be reverted.

Now imagine that for some reason, which happens very often, we need to split the DB operations in separate transactions. One such reason could be that in our code, parts 1 to 3, cleanup a lot of depended tables that our user participated in, while in part 4 we need to delete some non-critical stats.

Imagine that our DB operations become so intensive that our beloved relational DB server decides to punish us and starts locking too many rows and eventually fails the whole transaction. We could separate all the code in 2 transactions – critical and non-critical. We separate all sensitive tables cleanup operations from parts 1 to 3 in one transaction A and all stats cleanup operations in another transaction B.

The relational DB monster should be happy as it does not need to lock so much rows with implementation refined like that:

@Service
public class UsersServiceImpl implements UsersService {
  ...

  @Overwrite
  public void cleanupUsers() {
    cleanupUsersMainTables();
    cleanupUsersStatsTables();
  }

  @Transactional
  private void cleanupUsersMainTables() {
    callDbOperationsPart1();
    callDbOperationsPart2();
    callDbOperationsPart3();
  }

  @Transactional
  private void cleanupUsersStatsTables() {
    callDbOperationsPart4();
  }

  ...
}

What is worth noting in the code above is that our beloved IDE warns us that Methods annotated with ‘@Transactional’ must be overridable. To get rid of the warning we make the methods protected.

Running our beloved tests, we hit an Exception:

org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
    ...
    at org.test.UsersServiceImpl.cleanupUsersMainTables(UsersServiceImpl.java:239)
    at org.test.UsersServiceImpl.cleanupUsers(UsersServiceImpl.java:226)
    ...
    at com.sun.proxy.$Proxy95.cleanupUsers(Unknown Source)
    at org.test.UsersServiceImplTest.testCleanupUsers(UsersServiceImplTest.java:237)
    ...

Meaning our tested cleanupUsers() method is not running in a transaction at all. What the hell is going on here??

The Spring transnational behavior is well documented. Our methods cleanupUsersMainTables() and cleanupUsersStatsTables() are actually running without transactions. The main reason for this is the com.sun.proxy.$Proxy95 instances that are messing with our call stacktraces.

The wisdom: In order Spring to start the transaction process it must be able to alter our methods and inject code prior and post method call. This is achieved by creating a Proxy instance class that wraps our public interface methods. However, Spring can force us to use that proxy implementation only if we use the instance that he prepared for us, which can be done only by this:

  ...

  @Authowired
  UsersService usersService;

  ...

Then comes the question why do we have the transitional magic when the @Transnational is used over interface implemented methods, but is not honored when we call our internal protected methods?

The reason is that when we call the internal methods we are calling the implementation instance this. In order to fix our messy code we need to somehow create a Spring proxy for our internal methods. We should start using it and Spring will take care of the transaction. Or will it?

Let’s give it a try:

interface UsersServiceInternals {
  void cleanupUsersMainTables();

  void cleanupUsersStatsTables();
}

And now let’s force our UserServiceImpl to implement it:

@Service
public class UsersServiceImpl implements UsersService, UsersServiceInternals {
  ...

  @Overwrite
  public void cleanupUsers() {
    cleanupUsersMainTables();
    cleanupUsersStatsTables();
  }

  @Transactional
  @Overwrite
  public void cleanupUsersMainTables() {
    callDbOperationsPart1();
    callDbOperationsPart2();
    callDbOperationsPart3();
  }

  @Transactional
  @Overwrite
  public void cleanupUsersStatsTables() {
    callDbOperationsPart4();
  }

  ...
}

That should’ve solved the problem and we run the tests again but aaaaaaaaaaaa… same error occurred. What is going on here this time!!!!??!!!???

We found out that Spring has created a proxy class for our internal interface methods but this proxy is still not in use. Ergo, we must obtain an instance of it in order to use it, instead of using the this:

@Service
public class UsersServiceImpl implements UsersService, UsersServiceInternals {
  ...

  @Autowired
  private ApplicationContext applicationContext;

  ...

  @Overwrite
  public void cleanupUsers() {
    getSpringProxy().cleanupUsersMainTables();
    getSpringProxy().cleanupUsersStatsTables();
  }

  @Transactional
  @Overwrite
  public void cleanupUsersMainTables() {
    callDbOperationsPart1();
    callDbOperationsPart2();
    callDbOperationsPart3();
  }

  @Transactional
  @Overwrite
  public void cleanupUsersStatsTables() {
    callDbOperationsPart4();
  }

  private UsersServiceInternals getSpringProxy() {
    return applicationContext.getBean(UsersServiceInternals.class);
  }

  ...
}

Now we can start the tests again and this time voila they all pass!

This is a story how knowing the basics of the Spring proxification helped us navigate in the Spring wonderland.