@Transaction(propagation = Propagation.REQUIRES_NEW) is not visible in MS SQL stored procedure

Viewed 357

I have encountered the following and I would like to see if anyone has seen this before or could provide me with an explanation.

I have a stored procedure that it needs to run in a single transaction. Particularly, the stored procedure contains these lines of code:

set @v_nested_transactions = @@trancount;

if @v_nested_transactions = 0
begin
  raiserror('Error: must be within a single transaction', 11, 1);
end
else if @v_nested_transactions >= 2
begin
  raiserror('Error: must not be used within nested transactions', 11, 1);
end;

I am using Spring and mybatis to call the stored procedure. I am using a facade layer which calls the service -> repository -> DAO. The calls are made as follows:

Facade layer

@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void callProcedure(final long id) {
    callProcedureService.callProcedure(id);
}

Service layer:

@Override
public void callProcedure(final long id) {
    CallProcedureRepository.callProcedure(id);
}

Repository:

public void callProcedure(final long id) {
    callProcedureDao.callProcedure(id);
}

DAO layer:

@Override
@Transactional(propagation = Propagation.MANDATORY)
public void callProcedure(final long id) {
    final Map<String, Object> parameters = new HashMap<>();
    parameters.put("id", id);
    this.sqlSession.update("callProcedure", parameters);
}

The stored procedure is called from an SQL map using mybatis-spring. The class that is calling the update is the SQLSessionTemplate.class. The sql map looks like this:

<update id="callProcedure" statementType="CALLABLE" parameterType="map">
    {CALL package.callProcedure(
      #{id, mode=IN, jdbcType=NUMERIC})}
</update>

Lastly, I am using the following in the persistence-context.xml of the Spring project.

<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

The stored procedure works as intended. I have tested that by removing the @@trancount check.

My problem is that the stored procedure always throws an error "Error: must be within a single transaction'. After running a few tests, it seems that spring correctly creates a new transaction for the stored procedure and if something goes wrong the transaction is rolledback with no issues. However, the transaction appears not to be visible in the transaction manager in MS SQL server; meaning that @@trancount always return 0.

Has anyone experience this problem before? Is there a workaround that I could use?

Thanks

0 Answers
Related