详解Spring MVC事务配置
在Spring MVC中,事务是一种常用的机制,它可以保证数据库操作的一致性和完整性。本文将详细介绍Spring MVC事务配置的完整攻略,包括事务的基本概念、事务的配置方式、事务的传播行为、事务的隔离级别等内容,并提供两个示例说明。
事务的基本概念
事务是指一组数据库操作,这些操作要么全部执行成功,要么全部执行失败。在Spring MVC中,事务是通过TransactionManager来管理的。TransactionManager是Spring框架提供的一个事务管理器,它可以管理多种事务实现方式,如JDBC事务、Hibernate事务、JPA事务等。
事务的配置方式
在Spring MVC中,事务的配置方式有两种:基于注解的事务配置和基于XML的事务配置。
基于注解的事务配置
基于注解的事务配置是一种简单、方便的事务配置方式。在Spring MVC中,我们可以使用@Transactional注解来标记需要进行事务管理的方法。@Transactional注解可以用于类或方法上,用于标记需要进行事务管理的类或方法。
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public void addUser(User user) {
userDao.addUser(user);
}
@Override
public void updateUser(User user) {
userDao.updateUser(user);
}
@Override
public void deleteUser(Long id) {
userDao.deleteUser(id);
}
@Override
public User getUserById(Long id) {
return userDao.getUserById(id);
}
@Override
public List<User> getAllUsers() {
return userDao.getAllUsers();
}
}
在上面的示例中,我们使用@Transactional注解标记了UserServiceImpl类,表示该类中的所有方法都需要进行事务管理。
基于XML的事务配置
基于XML的事务配置是一种更加灵活、可配置性更强的事务配置方式。在Spring MVC中,我们可以使用XML配置文件来配置事务管理器和事务通知器。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="get*" propagation="SUPPORTS"/>
<tx:method name="getAll*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="userServicePointcut" expression="execution(* com.example.service.UserService.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointcut"/>
</aop:config>
在上面的示例中,我们使用
事务的传播行为
在Spring MVC中,事务的传播行为是指在多个事务方法相互调用时,事务如何传播的问题。Spring MVC提供了7种事务传播行为,分别是REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER和NESTED。
REQUIRED
REQUIRED表示当前方法必须在一个事务内执行,如果当前存在事务,则加入该事务,否则创建一个新事务。
SUPPORTS
SUPPORTS表示当前方法不需要在一个事务内执行,如果当前存在事务,则加入该事务,否则以非事务方式执行。
MANDATORY
MANDATORY表示当前方法必须在一个事务内执行,如果当前不存在事务,则抛出异常。
REQUIRES_NEW
REQUIRES_NEW表示当前方法必须在一个新的事务内执行,如果当前存在事务,则挂起该事务,并创建一个新事务。
NOT_SUPPORTED
NOT_SUPPORTED表示当前方法不需要在一个事务内执行,如果当前存在事务,则挂起该事务。
NEVER
NEVER表示当前方法不允许在一个事务内执行,如果当前存在事务,则抛出异常。
NESTED
NESTED表示当前方法必须在一个嵌套事务内执行,如果当前存在事务,则在该事务内嵌套一个新事务。
事务的隔离级别
在Spring MVC中,事务的隔离级别是指多个事务同时操作同一个数据时,事务之间的隔离程度。Spring MVC提供了4种事务隔离级别,分别是DEFAULT、READ_UNCOMMITTED、READ_COMMITTED和REPEATABLE_READ。
示例
以下是两个示例演示如何在Spring MVC中配置事务:
示例一
-
创建一个名为spring-mvc-demo的Maven项目。
-
创建一个名为UserDao的DAO类。
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void addUser(User user) {
String sql = "INSERT INTO user(username, password) VALUES(?, ?)";
jdbcTemplate.update(sql, user.getUsername(), user.getPassword());
}
public void updateUser(User user) {
String sql = "UPDATE user SET username = ?, password = ? WHERE id = ?";
jdbcTemplate.update(sql, user.getUsername(), user.getPassword(), user.getId());
}
public void deleteUser(Long id) {
String sql = "DELETE FROM user WHERE id = ?";
jdbcTemplate.update(sql, id);
}
public User getUserById(Long id) {
String sql = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
}
public List<User> getAllUsers() {
String sql = "SELECT * FROM user";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
}
}
在上面的示例中,我们创建了一个名为UserDao的DAO类,并使用@Repository注解标记它。在DAO中,我们使用JdbcTemplate来操作数据库,并提供了addUser、updateUser、deleteUser、getUserById和getAllUsers方法来添加、更新、删除、查询用户。
- 创建一个名为UserService的Service类。
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public void addUser(User user) {
userDao.addUser(user);
}
@Override
public void updateUser(User user) {
userDao.updateUser(user);
}
@Override
public void deleteUser(Long id) {
userDao.deleteUser(id);
}
@Override
public User getUserById(Long id) {
return userDao.getUserById(id);
}
@Override
public List<User> getAllUsers() {
return userDao.getAllUsers();
}
}
在上面的示例中,我们创建了一个名为UserServiceImpl的Service类,并使用@Service注解标记它。在Service中,我们使用@Autowired注解将UserDao注入到Service中,并使用@Transactional注解标记该类,表示该类中的所有方法都需要进行事务管理。
- 创建一个名为UserController的Controller类。
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/")
public void addUser(@RequestBody User user) {
userService.addUser(user);
}
@PutMapping("/")
public void updateUser(@RequestBody User user) {
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable("id") Long id) {
userService.deleteUser(id);
}
@GetMapping("/{id}")
public User getUserById(@PathVariable("id") Long id) {
return userService.getUserById(id);
}
@GetMapping("/")
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
在上面的示例中,我们创建了一个名为UserController的Controller类,并使用@RestController注解标记它。在Controller中,我们使用@Autowired注解将UserService注入到Controller中,并使用@PostMapping、@PutMapping、@DeleteMapping、@GetMapping注解标记处理POST、PUT、DELETE、GET请求的方法。
示例二
-
创建一个名为spring-mvc-demo的Maven项目。
-
创建一个名为UserDao的DAO类。
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void addUser(User user) {
String sql = "INSERT INTO user(username, password) VALUES(?, ?)";
jdbcTemplate.update(sql, user.getUsername(), user.getPassword());
}
public void updateUser(User user) {
String sql = "UPDATE user SET username = ?, password = ? WHERE id = ?";
jdbcTemplate.update(sql, user.getUsername(), user.getPassword(), user.getId());
}
public void deleteUser(Long id) {
String sql = "DELETE FROM user WHERE id = ?";
jdbcTemplate.update(sql, id);
}
public User getUserById(Long id) {
String sql = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
}
public List<User> getAllUsers() {
String sql = "SELECT * FROM user";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
}
}
在上面的示例中,我们创建了一个名为UserDao的DAO类,并使用@Repository注解标记它。在DAO中,我们使用JdbcTemplate来操作数据库,并提供了addUser、updateUser、deleteUser、getUserById和getAllUsers方法来添加、更新、删除、查询用户。
- 创建一个名为UserService的Service类。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void addUser(User user) {
userDao.addUser(user);
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void updateUser(User user) {
userDao.updateUser(user);
}
@Override
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public void deleteUser(Long id) {
userDao.deleteUser(id);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
public User getUserById(Long id) {
return userDao.getUserById(id);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS, isolation = Isolation.READ_COMMITTED)
public List<User> getAllUsers() {
return userDao.getAllUsers();
}
}
在上面的示例中,我们创建了一个名为UserServiceImpl的Service类,并使用@Service注解标记它。在Service中,我们使用@Autowired注解将UserDao注入到Service中,并使用@Transactional注解标记该类,表示该类中的所有方法都需要进行事务管理。在@Transactional注解中,我们使用propagation属性来指定事务的传播行为,使用isolation属性来指定事务的隔离级别。
- 创建一个名为UserController的Controller类。
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/")
public void addUser(@RequestBody User user) {
userService.addUser(user);
}
@PutMapping("/")
public void updateUser(@RequestBody User user) {
userService.updateUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable("id") Long id) {
userService.deleteUser(id);
}
@GetMapping("/{id}")
public User getUserById(@PathVariable("id") Long id) {
return userService.getUserById(id);
}
@GetMapping("/")
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
在上面的示例中,我们创建了一个名为UserController的Controller类,并使用@RestController注解标记它。在Controller中,我们使用@Autowired注解将UserService注入到Controller中,并使用@PostMapping、@PutMapping、@DeleteMapping、@GetMapping注解标记处理POST、PUT、DELETE、GET请求的方法。在UserService中,我们使用@Transactional注解标记该类,表示该类中的所有方法都需要进行事务管理。在@Transactional注解中,我们使用propagation属性来指定事务的传播行为,使用isolation属性来指定事务的隔离级别。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Spring MVC事务配置 - Python技术站