简体   繁体   English

spring-hibernate transactional不要回滚

[英]spring-hibernate transactional dont rollback

The HQL statement does not roll back when I use spring+hibernate, but session.saveOrUpdate () will; 当我使用spring + hibernate时,HQL语句不会回滚,但是session.saveOrUpdate ()将会回滚;

UserService UserService

@Service
@Transactional(rollbackFor=Exception.class)
public class UserService {

    @Autowired
    private BaseDao dao;

    public int updateTest(){
        int i = dao.updateUser();
        int t = 1/0;
        return i;
    }
}

BaseDao BaseDao

@Repository
public class BaseDao {

     @Autowired
     private SessionFactory sessionFactory;

     private Session getSession(){
         return sessionFactory.getCurrentSession();
     }

     public int updateUser(){
         int i = 0;
        /* String sql = "from Student where name = 'dengbojing'";
         Query query = this.getSession().createQuery(sql);*/
         Student s = new Student();
         s.setId(1);
         s.setAddress("1");

         Query query = this.getSession().createQuery("update Student s set s.address = '1'");


         query.executeUpdate();

         //this.getSession().update(s);
         return i;
     }

}

Configuration class 配置类

@Configuration
@EnableConfigurationProperties(HibernateProperties.class)
@EnableTransactionManagement(proxyTargetClass=true)
public class HibernateConfig {
    @Autowired
    private HibernateProperties config;


    @Bean(name="sessionFactory")
    public LocalSessionFactoryBean localSessionFactoryBean(){
        LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
        bean.setDataSource(dataSource());
        bean.setHibernateProperties(config.getHibernateProperties());
        bean.setPackagesToScan(config.getPackageToScan());
        return bean;
    }

    @Bean
    public DataSource dataSource(){
        DruidDataSource source = new DruidDataSource();
        source.setDriverClassName(config.getDatasource().getDriverClassName());
        source.setUsername(config.getDatasource().getUsername());
        source.setUrl(config.getDatasource().getUrl());
        source.setPassword(config.getDatasource().getPassword());
        return source;
    }

    @Bean
    public HibernateTransactionManager txManager(){
        HibernateTransactionManager manager = new HibernateTransactionManager();
        manager.setSessionFactory(localSessionFactoryBean().getObject());
        manager.setDataSource(dataSource());
        return manager;
    }

}

Spring transaction does not support the HQL statement, the problem plagued me for 2 days, I saw someone with similar problems, but did not solve the problem Spring事务不支持HQL语句,问题困扰了我2天,我看到有类似问题的人,但没有解决问题

I have made some tests with exact same versions and configuration. 我已经使用完全相同的版本和配置进行了一些测试。

I have to say that the update is never persisted in the database. 我不得不说数据库中永远不会保留更新。

As a workaround, if you can implement your functionality in this way.. try to: 作为解决方法,如果您可以通过这种方式实现您的功能..尝试:

  • Find the desired Person entity 找到所需的Person实体
  • Update required fields 更新必填字段
  • Do not invoke any other methods on the session object after that.. just leave it to the framework to update the changes on the transaction commit. 之后不要在会话对象上调用任何其他方法。只需将其留给框架来更新事务提交的更改。

Example

Person person = session.get(Person.class, 1);

person.setAddress("1")
// other fields updated

return i;

Now, without the explicit bulk update using the executeUpate() there is no chance for an implicit commit by the provider.. This is theory so check it out. 现在,如果没有使用executeUpate()进行显式批量更新,则提供者无法进行隐式提交。这是理论所以请查看它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM