Spring超详细讲解事务
什么是事务
事务是指一个操作序列,该操作序列中的所有操作都必须全部执行成功或全部执行失败。事务支持保证数据库的一致性、完整性和隔离性。
Spring事务的优点
在使用Spring进行数据库操作时,使用Spring事务能够带来以下优点:
- Spring事务对所有的数据库访问代码提供了一致的编程模型
- Spring事务可以将数据库事务的边界引入到不同的服务方法之间,而不是只在单个服务方法中使用
- Spring事务提供了面向切面编程的方式来声明性地管理事务。这使得开发人员不必在业务逻辑中编写事务代码
Spring事务类型
Spring事务支持以下类型:
- 编程式事务:通过编写代码来管理事务
- 声明式事务:通过配置声明式事务管理器来管理事务
声明式事务是比较常用的一种方式,因为它可以通过配置来管理事务而不需要编写大量的重复代码。
Spring声明式事务的配置
要使用声明式事务,需要完成以下步骤:
- 配置数据源
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="initialSize" value="5"/>
<property name="maxTotal" value="10"/>
</bean>
- 配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
- 配置基于注解的声明式事务
<tx:annotation-driven transaction-manager="transactionManager"/>
以上配置需要在Spring配置文件中进行。
Spring事务的注解
-
@Transactional:用于声明一个方法是事务方法,即该方法执行过程中如果出现异常会进行事务回滚。
-
@Transactional(propagation=Propagation.REQUIRED):如果当前方法正在一个事务中运行,那么这个事务将被继续使用,而不是重新开启一个新的事务。如果当前方法没有在一个事务中运行,那么这个方法将会开启一个新的事务。
-
@Transactional(propagation=Propagation.REQUIRES_NEW):该方法必须开启一个新的事务。如果当前方法已经在一个事务中运行,那么当前事务将被挂起,新的事务将被开启。
Spring事务示例
示例1:使用注解管理事务
创建一个UserService接口和一个UserServiceImpl类:
public interface UserService {
List<User> findAll();
void transfer(int fromId, int toId, double money);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
return userDao.findAll();
}
@Override
@Transactional(propagation=Propagation.REQUIRED)
public void transfer(int fromId, int toId, double money) {
userDao.update(fromId, -money);
int i = 1/0; // 抛出异常
userDao.update(toId, money);
}
}
- 使用@Autowired注解进行依赖注入;
- 使用@Transactional注解声明transfer方法是事务方法;
- 在transfer方法中模拟转账操作,如果在转账过程中发生异常,就会进行事务回滚。
示例2:使用XML配置管理事务
创建一个UserService接口和一个UserServiceImpl类:
public interface UserService {
List<User> findAll();
void transfer(int fromId, int toId, double money);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
return userDao.findAll();
}
@Override
public void transfer(int fromId, int toId, double money) {
userDao.update(fromId, -money);
int i = 1/0; // 抛出异常
userDao.update(toId, money);
}
}
- 使用@Autowired注解进行依赖注入。
创建一个UserDao类:
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<User> findAll() {
return jdbcTemplate.query("SELECT * FROM user", new BeanPropertyRowMapper<>(User.class));
}
public void update(int id, double money) {
jdbcTemplate.update("UPDATE user SET balance=balance+? WHERE id=?", money, id);
}
}
- 使用@Autowired注解进行依赖注入;
- 使用JdbcTemplate进行数据库操作。
在Spring配置文件中进行以下配置:
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="initialSize" value="5"/>
<property name="maxTotal" value="10"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDao" class="com.example.demo.dao.UserDao">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<bean id="userService" class="com.example.demo.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="userServicePointcut" expression="execution(* com.example.demo.service.UserService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointcut"/>
</aop:config>
- 配置数据源、JdbcTemplate、事务管理器、UserDao、UserService;
- 配置事务增强和切入点。
总结
本篇文章介绍了Spring事务的概念、优点、类型和注解,以及如何使用注解和XML配置管理事务,并提供了两个示例。使用Spring事务能够使代码更简洁、更规范化、更易于维护,提高代码质量和开发效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring超详细讲解事务 - Python技术站