spring事务管理配置初学

本文介绍了一个结合使用jdbcTemplate和hibernateTemplate的例子,并通过配置Spring的HibernateTransactionManager实现了两者之间的事务共享。文中详细展示了如何配置数据源、SessionFactory及事务管理器,并通过具体的代码示例说明了如何在业务逻辑中实现事务的控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

简单的记录使用spring事物的一些问题

正文

jdbcTemplate与hibernateTemplate事物的管理

<bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

在自己的项目中配置了上面的事务管理,在想,如果是jdbcTemplate,这个HibernateTransactionManager还适用吗?查了一下资料,如jdbcTemplate与hibernateTemplate事务共享配置

《Hibernate与JdbcTemplate共享事务管理》
《Hibernate 与spring jdbcTemplate共享事物的管理》
《HibernateTransactionManager事务管理》

从上面文章自己做了以下的配置以及代码测试

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-4.0.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
               ">

    <context:property-placeholder location="classpath:config/mysql.properties"/>
    <context:component-scan base-package="org.test" />
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${jdbc.driverClassName}" />  
        <property name="url" value="${jdbc.url}" />  
        <property name="username" value="${jdbc.username}" />  
        <property name="password" value="${jdbc.password}" />  
    </bean>  
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <!-- 依赖注入数据源,注入正是上面定义的dataSource -->
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
       <list>
        <value>myblog.pojo</value>
        <!--<value>com.myzone.exam.pojo.OptionsPO</value>
        <value>com.myzone.exam.pojo.SubjectsPO</value>
        <value>com.myzone.exam.pojo.SubjectTypePO</value>
       --></list>
    </property>
        <!-- 定义Hibernate的SessionFactory的属性 -->
    <property name="hibernateProperties">
        <props>
            <!-- 指定数据库方言 -->
            <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQLInnoDBDialect</prop>
            <!-- 是否根据需要每次自动创建数据库 -->
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <!-- 显示Hibernate持久化操作所生成的SQL -->
            <prop key="hibernate.show_sql">true</prop>
            <!-- 将SQL脚本进行格式化后再输出 -->
            <prop key="hibernate.format_sql">true</prop>
        </props>
    </property>
</bean>

     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
     </bean>

     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
         <property name="sessionFactory" ref="sessionFactory"></property>
     </bean>

    <!-- 定义事务管理器(声明式的事务) -->  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="interceptorPointCuts"
            expression="execution(* org.test.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice"
            pointcut-ref="interceptorPointCuts" />        
    </aop:config>   

</beans>

上面事物管理使用框架提供的org.springframework.orm.hibernate4.HibernateTransactionManager
在里面就配置了一个sessionFactory(可以成功因为共用一个数据源?)

代码-service层

public void register(RegisterDTO dto) {
        //是否存在用户
        if(userDao.findUser(dto) != null) {
            throw new RuntimeException("已经存在用户");
        }
        //注册用户,使用jdbcTempalte插入用户信息
        int userid = userDao.addUser(dto);
        //使用hibernate插入用户信息
        System.out.println("hiberante输出:" + userDao.addUserByHibernate(dto));
        //注册登录信息
        dto.setUserid(userid);
        logonDao.addLogon(dto);
        //抛出异常回滚
        throw new RuntimeException();
}

代码-userDao

@Override
    public int addUser(final RegisterDTO dto) {
        String sql = "insert into user1(displayname) values(?);";
        KeyHolder key = new GeneratedKeyHolder();
        int result = jdbcTemplate.update(new PreparedStatementCreator(){
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, dto.getDisplayname());
                return ps;
            }
        }, key);
        if(result == 0) {
            throw new RuntimeException("对数据库没有影响,因为操作的结果返回为0");
        }
        return key.getKey().intValue();
    }

public int addUserByHibernate(RegisterDTO dto) {
        final String sql = "insert into user1(displayname) values(:displayname);";
        final String displayname = dto.getDisplayname();
        return hiberanteTemplate.executeWithNativeSession(new HibernateCallback<Integer>() {
            @Override
            public Integer doInHibernate(Session session) throws HibernateException {
                Query query = session.createSQLQuery(sql);
                query.setParameter("displayname", displayname);
                return query.executeUpdate();
            }
        });
    }

备注:第二个方法使用hibernateTemplate的Query来插入用户信息,不需要配置hibernate与数据库的映射关系(这里使用注解),如果是hibernate.save(Entity)保存实体类的话,需要配置orm的关系(这里不再配置文件配置,而是注解)

代码-单元测试

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:config/spring-config.xml") 
public class RegisterServiceTest {

    @Resource(name="registerService")
    private IRegisterService service;

    @Test
    public void registerTest() {
        RegisterDTO dto = new RegisterDTO();
        dto.setDisplayname("superman123");
        dto.setPassword("99999");
        service.register(dto);
    }

}

备注:单元测试如上,可以获取IOC容器中的对象实现注入,service层、dao层使用@Component (@controller 控制器(注入服务) 2、@service 服务(注入dao) 3、@repository dao(实现dao访问))实现bean定义,在单元测试也能从IOC容器中获取。效果反正和启动服务器访问差不多,上面我少配置了@Transactional,这个注解,在单元测试完,自动回滚,所以我取消掉了

经过测试,上面操作可以在抛出异常的时候对jdbcTemplate方法和hibernateTemplate方法进行回滚

问题

对注解@Transactional这里有点迷糊
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值