HibernateTransactionManager事务管理
来源:互联网 发布:写一个动态数组模板类 编辑:程序博客网 时间:2024/04/19 11:15
配置JdbcTemplate
:
先配置数据源:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mkyongjava" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean>
在配置JdbcTemplate
JdbcCustomerDAO
继承JdbcTemplate
<bean id="customerDAO" class="com.mkyong.customer.dao.impl.JdbcCustomerDAO"> <property name="dataSource" ref="dataSource" /> </bean>
配置HibernateTemplate
<context:property-placeholder location="jdbc.properties" /> <!-- c3p0数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 驱动程序 --> <property name="driverClass"> <value>${jdbc.driverClass}</value> </property> <!-- 连接的url地址 --> <property name="jdbcUrl"> <value>${jdbc.url}</value> </property> <!-- 连接的用户名 --> <property name="user"> <value>${jdbc.user}</value> </property> <!-- 连接的密码 --> <property name="password"> <value>${jdbc.password}</value> </property> <!-- 最大池数 --> <property name="maxPoolSize"> <value>${c3p0.pool.max}</value> </property> <!-- 最小池数 --> <property name="minPoolSize"> <value>${c3p0.pool.min}</value> </property> <!-- 默认初始化的池数 --> <property name="initialPoolSize"> <value>${c3p0.pool.init}</value> </property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 设置数据源 --> <property name="dataSource" ref="dataSource" /> <!-- 属性设置 --> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> </props> </property> <!-- 映射文件配置 --> <property name="mappingResources"> <list> <value>cn/csdn/domain/Customer.hbm.xml</value> </list> </property> </bean> <!-- hibernate模板 --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
如果一个方法中既用了HibernateTemplate
,又用了JdbcTemplate
,应该怎么配事务?用 DataSouceTransactionManager
是不行的,而用HibernateTransactionManager
就可以保证 HibernateTransactionManager
可以保证SessionFactoryUtil
和DataSourceUtil
都能在一个事务里取到同一个连接
在一个service方法里面,用了jdbcdaosupport
的dao又用了hibernateDaoSupport
的dao,在spring里面给service方法配上了事务,
但是通过mysql的bin log,发现这种不同的dao使用的连接id不是同一个,即jdbctemplate
使用了一个链接,而hibernatetemplate
使用了另外一个链接,虽然两种dao都是针对一个mysql实例,但却没法保证事务。
使用hibernateTransaction manager,可以保证混用时候的事务。我们这边就以为datasourcetransactionmanager也是一样,但发现事实上不一样。确实我们换成hibernateTransaction manager,两种dao使用的connection就归一了,真好,但是为啥呢?
以下是datasourceTransactionManager
的doGetTransaction
和doBegin
代码
protected Object doGetTransaction() { //只是设定一个dataSource为key的存放connection的threadlcal DataSourceTransactionObject txObject = new DataSourceTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource); txObject.setConnectionHolder(conHolder, false); return txObject; } protected void doBegin(Object transaction, TransactionDefinition definition) { ..... try { if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); } .... //从datasource拿一个连接,放入thread生命周期的holder }
这就完了。
然后jdbctemplate会通过datasourceutil去拿这个holder里面的connection
从而在一个事务里使用这个连接。
但是hibernateTransactionManager呢:
protected Object doGetTransaction() { HibernateTransactionObject txObject = new HibernateTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); if (sessionHolder != null) { if (logger.isDebugEnabled()) { logger.debug("Found thread-bound Session [" + SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction"); } txObject.setSessionHolder(sessionHolder, false); } if (getDataSource() != null) { ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(getDataSource()); txObject.setConnectionHolder(conHolder); } return txObject; } //两个holder都管! protected void doBegin(Object transaction, TransactionDefinition definition) { ..... try { if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) { Interceptor entityInterceptor = getEntityInterceptor(); Session newSession = (entityInterceptor != null ? getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession()); if (logger.isDebugEnabled()) { logger.debug("Opened new Session [" + SessionFactoryUtils.toString(newSession) + "] for Hibernate transaction"); } txObject.setSessionHolder(new SessionHolder(newSession), true); } ..... //从sessionFactory拿个新session,也会产生一个新连接 session = txObject.getSessionHolder().getSession(); if (this.prepareConnection && isSameConnectionForEntireSession(session)) { // We're allowed to change the transaction settings of the JDBC Connection. if (logger.isDebugEnabled()) { logger.debug( "Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]"); } //原来直接把session后面的connection也放入holder Connection con = session.connection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); }
所以如果使用hibernateTransactionManager的话,就完全可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接!所有的疑问烟消云散了,
所以大家还是使用hibernateTransactionManager从而随心所欲的使用jdbctemplate和hibernatetemplate吧
- HibernateTransactionManager事务管理
- HibernateTransactionManager事务管理
- HibernateTransactionManager 事务管理实现
- Spring事务管理之HibernateTransactionManager
- HibernateTransactionManager管理事务
- HibernateTransactionManager事物管理
- HibernateTransactionManager配单例事务
- HibernateTransactionManager和DataSourceTransactionManager
- HibernateTransactionManager和DataSourceTransactionManager
- spring事物控制--HibernateTransactionManager
- HibernateTransactionManager和DataSourceTransactionManager
- hibernateTransactionManager的问题
- 事务管理
- 事务管理
- 事务管理
- 事务管理
- 事务管理
- 事务管理
- jsoncpp数组下标为0时的访问注意事项 这样应该算是严重bug
- 一个监听数字加减变化的自定义控件
- Android应用的耗电量统计
- [LeetCode]Ugly Number
- sidekiq 异步处理任务
- HibernateTransactionManager事务管理
- HDU 5463 Clarke and minecraft(模拟)
- 即时战略游戏中实用的寻路算法都有哪些,比较如何?
- matlab uigetfile()的使用
- Effective C++——条款50(第8章)
- Warning: Maximum number of format records exceeded. Using default format.
- js之DOM操作(删除节点removeChild())
- MVC模型优化方案
- 在Mysql 众多表中查找一个表名或者字段名