Should I use beginTransaction when using @Transactional?
I am rather confused about Spring and Hibernate transactions. I have the following sample code.
I am wondering if
- This is the right way to search or not.
- Should I use
getCurrentSession().beginTransaction()
, should I use it together 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);
}
}
source to share
The annotation @Transactional
itself defines the scope of a single database transaction. The database transaction takes place inside the scope of the persistence context.
The persistence context is simply a synchronizer object that keeps track of the state of a limited set of Java objects and ensures that changes to those objects are eventually persisted to the database.
For annotation, @Transactional
you can set the propagation attribute using Propagation , you can handle your tarnsaction differently like Propagation.REQUIRES_NEW
(if you need a new transaction on every request). the default distribution is REQUIRED
.
session.beginTransaction()
will also either start a new transaction if there is none, or will use an existing transaction to start the specified unit of work.
Thus, you must use either one of the transaction control methods.
source to share
-
Yes, to only use
@Transactional
annotation when you are using Spring for transaction management. -
Not. You don't need to do this! If you use annotation
@Transactional
in your service, then Spring takes care of your persistence layer for transaction management. All you need to do is declare a level-persistent transaction manager in your Spring configuration. This way you don't need to manage the transaction with hibernation sessions using insession.beginTransaction()
conjunction with@Transactional
.
See the usage documentation for@Transactional
more information .
source to share