我应该在使用@Transactional时使用beginTransaction吗? [英] Should I use beginTransaction while using @Transactional?

查看:113
本文介绍了我应该在使用@Transactional时使用beginTransaction吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Spring和Hibernate事务很困惑。我有以下示例代码。



我想知道是否


  1. 这是一种正确的检索方式。

  2. 我是否应该使用 getCurrentSession()。beginTransaction()以及 @ b

    配置

     < bean id =dataSourceclass =org.apache.commons.dbcp2.BasicDataSource
    destroy-method =close> ;
    < property name =driverClassNamevalue =com.mysql.jdbc.Driver/>
    < property name =urlvalue =jdbc:mysql:// localhost:2000 / HiberProject/>
    < property name =usernamevalue =jack/>
    < property name =passwordvalue =jack/>
    < / bean>

    < bean id =sessionFactory
    class =org.springframework.orm.hibernate4.LocalSessionFactoryBean
    depends-on =dataSource>
    < property name =dataSourceref =dataSource/>
    < property name =packagesToScanvalue =com.hiberproject.model/>
    < property name =hibernateProperties>
    <道具>
    < prop key =hibernate.format_sql> true< / prop>
    < prop key =hibernate.use_sql_comments> true< / prop>
    < prop key =hibernate.show_sql> true< / prop>
    < prop key =hibernate.hbm2ddl.auto> update< / prop>
    < /道具>
    < / property>
    < / bean>

    < bean
    class =org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor/>
    < bean id =transactionManager
    class =org.springframework.orm.hibernate4.HibernateTransactionManager>
    < property name =sessionFactoryref =sessionFactory/>
    < / bean>

    < tx:注解驱动的事务管理器=transactionManager/>

    服务

      @Service 
    public class SampleRecordsServiceImpl实现SampleRecordsService {
    $ b $ @Autowired
    SampleRecordsRepository sampleRecordsRepository;

    @Override
    @Transactional(readOnly = true)
    public记录retrieveRecord(long id){
    return sampleRecordsRepository.retrieveRecord(id);
    }
    }

    存储库

      @Repository 
    public class SampleRecordsRepository实现SampleRecordsRepository {
    $ b $ @Autowired
    SessionFactory sessioFactory;

    @Override
    public RecordRecordRecord(long id){
    return(Record)sessionFactory.getCurrentSession().get(Record.class,id);
    }
    }


    解决方案

    @Transactional 注释本身定义了单个数据库事务的范围。数据库事务发生在持久化上下文的范围内。

    持久化上下文只是一个同步器对象,用于跟踪有限的一组Java对象的状态,并确保对这些对象的更改最终会持久保存到数据库中。

    对于 @Transactional 注释,您可以使用 Propagation 你可以用不同的方式处理你的tarnsaction,比如 Propagation.REQUIRES_NEW (如果您需要每个请求的新事务)。默认传播是 REQUIRED



    session.beginTransaction()也将开始一个新的交易,如果一个不存在,或者它将使用一个现有的交易来开始指定的工作单元。



    所以你应该使用任何一种管理交易的方法。

    I am quite confused with Spring and Hibernate transactions. I have the following sample code.

    I am wondering if

    1. This is a correct way of retrieval or not.
    2. Should I use getCurrentSession().beginTransaction() as well, should I use it in conjunction with @Transactional at all?

    Configuration

     <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:2000/HiberProject" />
            <property name="username" value="jack" />
            <property name="password" value="jack" />
        </bean>
    
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
        depends-on="dataSource">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.hiberproject.model" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.use_sql_comments">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>
    
    <bean
      class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    <bean id="transactionManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager" />
    

    Service

    @Service
    public class SampleRecordsServiceImpl implements SampleRecordsService{
    
     @Autowired
     SampleRecordsRepository sampleRecordsRepository;
    
     @Override
     @Transactional(readOnly=true)
     public Record retrieveRecord(long id){
          return sampleRecordsRepository.retrieveRecord(id);
     }
    }
    

    Repository

    @Repository
    public class SampleRecordsRepository implements SampleRecordsRepository{
    
     @Autowired
     SessionFactory sessioFactory;
    
     @Override
     public Record retrieveRecord(long id){
         return (Record) sessionFactory.getCurrentSession().get(Record.class,id);
     }
    }
    

    解决方案

    The @Transactional annotation itself defines the scope of a single database transaction. The database transaction happens inside the scope of a persistence context.

    The persistence context is just a synchronizer object that tracks the state of a limited set of Java objects and makes sure that changes on those objects are eventually persisted back into the database.

    For @Transactional annotation you can set propagation attribute, using Propagation you can handle your tarnsaction in different way like Propagation.REQUIRES_NEW(if you need new transaction on every request) . the default propagation is REQUIRED.

    session.beginTransaction() will also either begin a new Transaction if one isn't present, or it will use an existing transaction to begin the unit of work specified.

    So you should use either one of approach to manage the transaction.

    这篇关于我应该在使用@Transactional时使用beginTransaction吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆