情况:
我已经安排了长达15分钟的任务。它重新生成2个表。我想在一次交易中这样做,但是对于@Transational,回购电话有2个不同的交易,用于大量的回购电话。
这是一个带有postgres的春季靴子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();
}
);
}
}
我不确定这是否会解决你的问题,但你真的不应该在static DSLContext
中有Service
参考,特别是因为你的DSLContext
引用了一个单独的Connection
。您的设计意味着任何JooqService
实现都将使用相同的JDBC连接。
我也怀疑你应该缓存你的JDBC Connection
。理想情况下,你的DSLContext
直接包裹DataSource
。这是通过从数据源正确获取Connection
并在使用后通过为您调用Connection.close()
再次释放jOOQ插入已配置的事务管理的最佳方式。