事务有什么用?
在涉及多个对数据库的增删改查事件中,可以保证整个事件的处理结果只有成功或者失败!
例如:去书店买书付款事件,执行流程就是书的库存减少,用户卡里的金额减少;如果你卡里面的金额不足,就会导致书的库存减少但是用户金额没有减少的情况!为了避免这个情况的发生,事务应运而生!
Spring中常用的两种配置事务的方式
1、注解
2、AOP切面
无论哪种配置方式的前提都是
1、数据源设置(连接配置)
<!-- 给底层数据源设置属性 -->
<bean id="basicDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
</bean>
通过sessionfactory对数据源的sql语句进行设置(控制台日志、映射文件)
<!-- 设置一个会话工厂一些属性,如显示sql语句,等等 -->
<bean id="sessionFactoryBean" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="basicDataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="current_session_context_class">thread</prop>
</props>
</property>
<!-- 添加映射文件 -->
<property name="mappingLocations">
<list>
<value>classpath:cn/com/bean/User.hbm.xml</value>
</list>
</property>
</bean>
2、采用hibernate或者mybatis对数据源进行管理(增删改查的语法)
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<!--管理sessionFactory工厂的 -->
<property name="sessionFactory" ref="sessionFactoryBean"></property>
</bean>
注解的方式
1、在类的方法上面添加@Transactional
package cn.com.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.bean.User;
@Service(value="regedit")
public class Regedit {
@Autowired
private SessionFactory sf;
@Transactional
public String login(){
System.out.println("i come");
Session session=sf.getCurrentSession();
User u=new User();
u.setPassword("1111111");
u.setUsername("谢弃尘");
session.save(u);
return "success";
}
}
2、这个事务注解的方式需要在配置文件里面设置才会生效
<tx:annotation-driven transaction-manager="transactionManager"/>
AOP切面(有豪豪复杂)
1、类(set和get方法)
package cn.com.service;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.bean.User;
public class Regedit {
private SessionFactory sf;
public SessionFactory getSf() {
return sf;
}
public void setSf(SessionFactory sf) {
this.sf = sf;
}
public String login(){
System.out.println("i come");
Session session=sf.getCurrentSession();
User u=new User();
u.setPassword("1111111");
u.setUsername("谢弃尘");
session.save(u);
return "success";
}
}
2、applicationContext.xml配置
<!-- 事务对sql语言框架配置-->
<tx:advice transaction-manager="transactionManager" id="txadvice">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 通过切面指定哪个类的哪个方法用事务管理 -->
<aop:config>
<aop:pointcut expression="execution(* cn.com.service.Regedit.login(..))" id="txpointcut"/>
<aop:advisor pointcut-ref="txpointcut" advice-ref="txadvice"/>
</aop:config>
<!-- 基础bean配置 -->
<bean id="regedit" class="cn.com.service.Regedit">
<property name="sf" ref="sessionFactoryBean"></property>
</bean>