【问题标题】:How to run custom query in the beginning of each transaction?如何在每个事务开始时运行自定义查询?
【发布时间】:2025-12-23 23:10:06
【问题描述】:

我在我的项目中使用 Firebird 数据库,而我在 DB 中的存储过程使用的是自定义 context variables,它是事务范围的。

我必须在每个事务开始时将一些变量设置为上下文。如何在不重复每个 @Transactional 注释方法中的代码的情况下实现这一点?

例子:

控制器

@RestController
@RequestMapping({TBL_EMPLOYEE, TBL_EMP})
public class EmployeeController extends EmployeeCommonController<Employee> {
         
@GetMapping(PATH_LASTLOGIN)
    public List<UserLastLoginWrapper> getUserLastLoginWrapper(Long userid, tring appname) {
        return getService().getUserLastLoginWrapper(userid, appname);
    }
}
    

服务

@Transactional
public class EmployeeService{
  public List<UserLastLoginWrapper> getUserLastLoginWrapper(Long userid, String appname) {
        return ((EmployeeRepository) getRepository()).getUserLastLoginWrapper(null, userid, appname);
    }
}

存储库

@NamedNativeQuery(name = "Employee.getUserLastLoginWrapper", query = "select * from SP_USER_LAST_LOGIN(:userid, :appname)", resultSetMapping = UserLastLoginWrapper.USERLASTLOGINWRAPPER)

大多数存储过程都试图从上下文变量中获取hotelrefno 信息,所以我必须在每个事务开始时调用execute procedure SP_CTX_SET_LOGIN_INFO(:hotelrefno, :userid) 过程。

【问题讨论】:

  • 请提供一些代码来说明您的问题
  • 在此处查看我的答案以获得基于 AOP 的解决方案(答案是指 Oracle,但应该与数据库相关):*.com/a/47809487/1356423

标签: java spring-boot spring-data-jpa firebird spring-transactions


【解决方案1】:

你可以创建一个Before Aspect

@Aspect
public class ProdcedureAspect {

    @Before("execution(* **.*Service.*(..))")
    public void doBefore(JoinPoint joinPoint) { 
       // execute procedure SP_CTX_SET_LOGIN_INFO(:hotelrefno, :userid)
    }
}

在此处阅读有关 Spring AOP 的更多信息:

https://docs.spring.io/spring/docs/5.1.7.RELEASE/spring-framework-reference/core.html#aop-api

【讨论】:

  • 这个答案也是正确的,但可能存在在同一个服务类方法中创建单独事务的情况。
【解决方案2】:

我在获得连接后调用此查询。请参阅下面的方面配置。

@AfterReturning(pointcut = "execution(* *.getConnection(..))", returning = "connection")
public Connection prepare(Connection connection) throws SQLException {
CallableStatement cs = connection.prepareCall(
                "execute procedure SP_CTX_SET_LOGIN_INFO(?,?,?,?)");
//....
}

【讨论】:

    最近更新 更多