Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use beginTransaction while using @Transactional?

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);
 }
}
like image 711
Jack Avatar asked Jun 02 '15 03:06

Jack


1 Answers

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.

like image 72
Sai prateek Avatar answered Nov 15 '22 10:11

Sai prateek