postgresql - 多个存储库上的 JOOQ @Transactional
问题描述
情况:
我已经安排了 15 分钟的长期任务。它重新生成 2 个表。我想在 ONE 交易中进行,但是对于大量的 repo 调用,使用 @Transational 的 repo 调用有 2 个不同的交易。
这是一个带有 postgres 的 spring boot 2 项目。
回购协议是否可能有不同的连接?
(我删除并简化了一些 DI。)
代码示例:
@Scheduled(...)
public class ScheduledTaskRunner
{
@Transactional
public void run()
{
aService.parseXML();
bService.parseCSV();
}
}
@Service
public class AService
{
public function parseXML()
{
for (Node node : parserMethodSomewhere())
{
aRepository.save(node.getDataA(), node.getDataB());
}
}
}
@Service
public class BService
{
public function parseCSV()
{
for (Node node : parserMethodSomewhere())
{
bRepository.save(node.getDataA(), node.getDataB());
}
}
}
@Service
public class ConnectionService
{
@Autowired
private DataSource dataSource;
private Connection connection = null;
public Connection getConnection() throws SQLException
{
if (null == connection)
{
connection = dataSource.getConnection();
}
return connection;
}
}
@Service
public class JooqService
{
@Autowired
private Connection connection;
private DSLContext dslContext = null;
public DSLContext createQueryBuilder()
{
if (null == dslContext)
{
this.dslContext = DSL.using(connection, SQLDialect.POSTGRES);
}
return dslContext;
}
}
@Repository
public abstract class AbstractRepository
{
@Autowired
private JooqService jooqService;
DSLContext createQueryBuilder()
{
return jooqService.createQueryBuilder();
}
}
public function ARepository extends AbstractRepository
{
public function save(int a, int b)
{
createQueryBuilder().insertInto(table, table.a, table.b).values(a, b).execute();
}
}
public function BRepository extends AbstractRepository
{
public function save(int a, int b)
{
createQueryBuilder().insertInto(table, table.a, table.b).values(a, b).execute();
}
}
=============================================== 解决方法 - 解决方案:
@Scheduled(...)
public class ScheduledTaskRunner
{
// @Transactional
public void run()
{
jooqService.createQueryBuilder().transaction(
(configuration) ->
{
aService.parseXML();
bService.parseCSV();
}
);
}
}
解决方案
我不确定这是否能解决你的问题,但你真的不应该在 astatic DSLContext
中引用Service
,尤其是因为你DSLContext
引用了个人Connection
。您的设计意味着任何JooqService
实现都将使用相同的 JDBC 连接。
我也怀疑你是否也应该缓存你的 JDBC Connection
。理想情况下,您直接DSLContext
包装DataSource
。这是将 jOOQ 插入您配置的事务管理的最佳方式,方法是Connection
从数据源正确获取 a,并在使用后通过调用Connection.close()
您再次释放它。
推荐阅读
- php - 如何检查 html/php 中的按钮是否被按下
- ruby-on-rails - 用于复杂类型数组的 Ruby on Rail 位运算符 (&)
- sql - 使用 SELECT 方法向 SQL 查询中的列添加数字值
- c# - 使用 USB 名称获取 USB 的序列号
- amazon-iam - AWS 假定角色无法在无服务器项目中执行 secretsmanager:GetSecretValue
- android - 我不能在我的模拟器上运行这个应用程序有人能帮我吗
- python - 在不同的会话中加载 TensorFlow 模型会产生不正确的结果
- javascript - 如果加载失败,如何重置 p5.js 草图
- python - 如果命令是函数的名称,如何运行函数?
- python - 使用数据透视表 pd 更改 python pandas 中的列顺序