我的代码与此代码非常相似:
dslContext.transaction(new TransactionalRunnable()
{
@Override
public void run(Configuration arg0) throws Exception
{
dao1.insert(object1);
//Object 1 is inserted in the database
//despite the exception that is being thrown
if(true)
throw new RuntimeException();
dao2.insert(object2)
}
});
这是我用来创建dsl上下文的代码和用JOOQ生成的daos。
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass(org.postgresql.Driver.class.getName());
comboPooledDataSource.setJdbcUrl("jdbc:postgresql://localhost:5432/database?searchpath=schema");
comboPooledDataSource.setUser("user");
comboPooledDataSource.setPassword("password");
comboPooledDataSource.setMinPoolSize(5);
comboPooledDataSource.setAcquireIncrement(5);
comboPooledDataSource.setMaxPoolSize(25);
Configuration configuration=new DefaultConfiguration().set(comboPooledDataSource).set(
SQLDialect.POSTGRES);
DSLContext dslContext=DSL.using(configuration);
Dao1 dao1=new Dao1(configuration);
Dao2 dao2=new Dao2(configuration);
为什么我会出现这种行为?
答案 0 :(得分:0)
您的DAO
配置的配置与您的交易不同。这意味着每个DAO在新的自动提交事务中运行其代码,即使您将该逻辑放在TransactionalRunnable
内。
这样可行:
dslContext.transaction(new TransactionalRunnable()
{
@Override
public void run(Configuration arg0) throws Exception
{
new Dao1(arg0).insert(object1);
if(true)
throw new RuntimeException();
new Dao2(arg0).insert(object2)
}
});
请注意,[DSLContext.transaction(TransactionalRunnable][1])
不会修改dslContext
及其随附的Configuration
。这意味着如果您的数据源无法正常工作,例如就像JavaEE或Spring TransactionAwareDataSourceProxy
一样,必须使用Configuration
方法的参数run()
来运行进一步的查询,方法是用{{1}包装它或者将它传递给你的daos。
一个更简单的选择是使用事务感知的数据源(即它将事务绑定到线程),这样同一个线程将始终从数据源获得相同的事务JDBC DSL.using(configuration)
。
答案 1 :(得分:0)
我让spring处理与jOOQ的交易。方法如下:
这是spring配置类:
@Configuration
public class SpringConfiguration
{
@Bean
public DataSource dataSource() throws PropertyVetoException
{
comboPooledDataSource.setDriverClass(org.postgresql.Driver.class.getName());
comboPooledDataSource
.setJdbcUrl("jdbc:postgresql://localhost:5432/database?searchpath=schema");
comboPooledDataSource.setUser("databaseuser");
comboPooledDataSource.setPassword("password");
comboPooledDataSource.setMinPoolSize(5);
comboPooledDataSource.setAcquireIncrement(5);
comboPooledDataSource.setMaxPoolSize(25);
return comboPooledDataSource;
}
@Bean
public DataSourceTransactionManager transactionManager() throws PropertyVetoException
{
return new DataSourceTransactionManager(dataSource());
}
@Bean
public TransactionAwareDataSourceProxy transactionAwareDataSource() throws PropertyVetoException
{
return new TransactionAwareDataSourceProxy(dataSource());
}
@Bean
public DataSourceConnectionProvider connectionProvider() throws PropertyVetoException
{
return new DataSourceConnectionProvider(transactionAwareDataSource());
}
@Bean
public org.jooq.Configuration configuration() throws PropertyVetoException
{
return new DefaultConfiguration().set(connectionProvider()).set(transactionProvider()).set(SQLDialect.POSTGRES);
}
@Bean
public TransactionProvider transactionProvider() throws PropertyVetoException
{
return new SpringTransactionProvider(transactionManager());
}
@Bean
public DSLContext dslContext() throws PropertyVetoException
{
return DSL.using(configuration());
}
}
这是SpringTransactionProvider
:
public class SpringTransactionProvider implements TransactionProvider
{
DataSourceTransactionManager transactionManager;
public SpringTransactionProvider(DataSourceTransactionManager transactionManager)
{
this.transactionManager = transactionManager;
}
@Override
public void begin(TransactionContext ctx)
{
TransactionStatus tx = transactionManager.getTransaction(new DefaultTransactionDefinition(
TransactionDefinition.PROPAGATION_REQUIRED));
ctx.transaction(new SpringTransaction(tx));
}
@Override
public void commit(TransactionContext ctx)
{
transactionManager.commit(((SpringTransaction) ctx.transaction()).tx);
}
@Override
public void rollback(TransactionContext ctx)
{
transactionManager.rollback(((SpringTransaction) ctx.transaction()).tx);
}
class SpringTransaction implements Transaction
{
final TransactionStatus tx;
SpringTransaction(TransactionStatus tx)
{
this.tx = tx;
}
}
}
最后得到DSLContext
:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
DSLContext dslContext=applicationContext.getBean(DSLContext.class);
您需要在类路径中使用这些jar才能使其正常工作:
spring-tx.jar
,spring-aop.jar
,spring-expression.jar
,spring-core.jar
,spring-beans.jar
,spring-jdbc.jar
和spring-context.jar
:)