我应该在使用@Transactional时使用beginTransaction吗? [英] Should I use beginTransaction while using @Transactional?
问题描述
我想知道是否
- 这是一种正确的检索方式。
- 我是否应该使用
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
- This is a correct way of retrieval or not.
- 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 likePropagation.REQUIRES_NEW
(if you need new transaction on every request) . the default propagation isREQUIRED
.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屋!