Java 使用spring 3/jdbctemplate和postgresql 9.3的事务
我尝试在我的应用程序中启用事务,但出现了一些问题 应用程序上下文:Java 使用spring 3/jdbctemplate和postgresql 9.3的事务,java,spring,postgresql,spring-mvc,Java,Spring,Postgresql,Spring Mvc,我尝试在我的应用程序中启用事务,但出现了一些问题 应用程序上下文: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost/db"/>
<property name="username" value="postgres"/>
<property name="password" value="postgres"/>
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
<constructor-arg name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
</beans>
(……)
dao类示例:
@Service
@Transactional
public class ProviderManager {
@Autowired private ProviderDao providerDao;
@Autowired private ProvisionDao provisionDao;
@Repository
public class ProvisionDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void save(Provider provider){
Timestamp now = new Timestamp(System.currentTimeMillis());
if(provider.getId() == null){
provider.setId(incrementer.nextLongValue());
String query = "insert into " + TABLE + " (" + COLUMNS + ") values (?)";
this.jdbcTemplate.update(query, new Object[]{ provider.getId() });
}else{
provider.setModificationDate(now);
String query = "update " + TABLE + " set " +
" MODIFICATION_DATE=?" +
" WHERE ID=?" ;
this.jdbcTemplate.update(query, new Object[]{
provider.getModificationDate(),
provider.getId()
});
}
}
当defaultAutocommit
设置为false时,我得到:
错误:org.springframework.dao.DataIntegrityViolationException:PreparedStatementCallback;SQL[在dict规定中插入(id、创建日期、创建用户、修改日期、修改用户、状态、提供者id、名称、数量)值(?,,,,,,,,,,,)];dict_提供程序中不存在外键
所以当defaultAutocommit
设置为true
时,即使在第二个方法中抛出异常,会话也不会看到第一次保存操作。我做的另一个测试:当这个参数设置为false时,不会保存任何内容
有人有同样的问题吗?如果有任何提示,我将不胜感激。您能粘贴这两个DAO方法的代码吗?您发布了应用程序上下文,但配置中没有声明服务。如果在不同的上下文中加载,则不会有任何事务性内容。其次,您的服务方法是有缺陷的,因为您永远不应该捕获并接受异常。这破坏了正确的发送管理。我用这两种方法复制/粘贴了简化版。够了吗?@M.Deinum:这就是重点!我有根contex和applicationContext,会话和数据库设置在第一个中,服务扫描在appcontex中,现在它在一个xml文件中,效果非常好!非常感谢你的帮助!
@Repository
public class ProvisionDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void save(Provider provider){
Timestamp now = new Timestamp(System.currentTimeMillis());
if(provider.getId() == null){
provider.setId(incrementer.nextLongValue());
String query = "insert into " + TABLE + " (" + COLUMNS + ") values (?)";
this.jdbcTemplate.update(query, new Object[]{ provider.getId() });
}else{
provider.setModificationDate(now);
String query = "update " + TABLE + " set " +
" MODIFICATION_DATE=?" +
" WHERE ID=?" ;
this.jdbcTemplate.update(query, new Object[]{
provider.getModificationDate(),
provider.getId()
});
}
}
@Repository
public class ProvisionDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void save(Provision provision){
Timestamp now = new Timestamp(System.currentTimeMillis());
if(provision.getId() == null){
provision.setId(incrementer.nextLongValue());
String query = "insert into " + TABLE + " (" + COLUMNS + ") values (?,?)";
this.jdbcTemplate.update(query, new Object[]{
provision.getId(),
provision.getProviderId()
});
}else{
provision.setModificationDate(now);
String query = "update " + TABLE + " set " +
" MODIFICATION_DATE=?" +
" WHERE ID=?" ;
this.jdbcTemplate.update(query, new Object[]{
provision.getModificationDate(),
provision.getId()
});
}
}