此文是 【Spring 容器详解】-> 【 ApplicationContext 做了哪些企业化的增强?】的支节点。
Spring的事务管理(Transaction Management)是ApplicationContext相对于BeanFactory的重要企业级增强功能。Spring提供了声明式和编程式两种事务管理方式,支持多种事务传播行为、隔离级别和回滚策略,为复杂的企业级应用提供了强大的事务支持。
1. BeanFactory的事务管理限制
1.1 BeanFactory的局限性
BeanFactory作为Spring的核心容器,在事务管理方面存在以下限制:
- 无内置事务支持:BeanFactory本身不提供事务管理功能
- 缺乏事务抽象:无法统一管理不同类型的事务
- 无事务注解支持:不支持@Transactional等事务注解
- 事务配置复杂:需要手动配置事务管理器和事务模板
1.2 示例代码
// BeanFactory缺乏事务支持
public class BeanFactoryTransactionExample {
public static void main(String[] args) {
// 创建BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// BeanFactory本身不提供事务功能
// 无法使用@Transactional注解
// 无法自动配置事务管理器
// 需要通过其他方式实现事务管理
// 手动实现事务管理
Connection connection = null;
try {
connection = getConnection();
connection.setAutoCommit(false);
// 执行业务逻辑
createUser(connection, "John Doe");
createUserProfile(connection, 1L);
// 提交事务
connection.commit();
System.out.println("事务提交成功");
} catch (Exception e) {
// 回滚事务
if (connection != null) {
try {
connection.rollback();
System.out.println("事务回滚成功");
} catch (SQLException ex) {
System.err.println("事务回滚失败: " + ex.getMessage());
}
}
throw new RuntimeException("事务执行失败", e);
} finally {
// 关闭连接
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
System.err.println("关闭连接失败: " + e.getMessage());
}
}
}
}
private static Connection getConnection() throws SQLException {
// 获取数据库连接
return DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "user", "password");
}
private static void createUser(Connection connection, String name) throws SQLException {
// 创建用户
String sql = "INSERT INTO users (name) VALUES (?)";
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
stmt.setString(1, name);
stmt.executeUpdate();
}
}
private static void createUserProfile(Connection connection, Long userId) throws SQLException {
// 创建用户档案
String sql = "INSERT INTO user_profiles (user_id, created_at) VALUES (?, ?)";
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
stmt.setLong(1, userId);
stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
stmt.executeUpdate();
}
}
}
2. ApplicationContext的事务管理扩展
2.1 核心注解:@EnableTransactionManagement
ApplicationContext通过@EnableTransactionManagement启用事务管理功能:
@Configuration
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
@Bean
public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
return new TransactionTemplate(transactionManager);
}
}
2.2 事务管理器的类型
Spring支持多种事务管理器:
@Configuration
public class TransactionManagerConfig {
// 1. 数据源事务管理器
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
// 2. JPA事务管理器
@Bean
public JpaTransactionManager jpaTransactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
// 3. Hibernate事务管理器
@Bean
public HibernateTransactionManager hibernateTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
// 4. JTA事务管理器
@Bean
public JtaTransactionManager jtaTransactionManager() {
JtaTransactionManager transactionManager = new JtaTransactionManager();
return transactionManager;
}
// 5. 链式事务管理器
@Bean
public ChainedTransactionManager chainedTransactionManager(
DataSourceTransactionManager dataSourceTransactionManager,
JpaTransactionManager jpaTransactionManager) {
return new ChainedTransactionManager(dataSourceTransactionManager, jpaTransactionManager);
}
}
3. 声明式事务管理
3.1 @Transactional注解详解
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private UserProfileRepository userProfileRepository;
// 1. 基本事务
@Transactional
public User createUser(String name, String email) {
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
User savedUser = userRepository.save(user);
// 创建用户档案
UserProfile profile = new UserProfile();
profile.setUserId(savedUser.getId());
profile.setCreatedAt(LocalDateTime.now());
userProfileRepository.save(profile);
return savedUser;
}
// 2. 指定传播行为
@Transactional(propagation = Propagation.REQUIRES_NEW)
public User createUserInNewTransaction(String name, String email) {
// 在新事务中创建用户
return createUser(name, email);
}
// 3. 指定隔离级别
@Transactional(isolation = Isolation.READ_COMMITTED)
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
// 4. 指定超时时间
@Transactional(timeout = 30)
public void updateUserBatch(List<User> users) {
for (User user : users) {
userRepository.save(user);
}
}
// 5. 指定回滚策略
@Transactional(rollbackFor = {SQLException.class, DataIntegrityViolationException.class})
public void createUserWithRollback(String name, String email) {
User user = new User();
user.setName(name);
user.setEmail(email);
userRepository.save(user);
// 如果这里抛出异常,事务会回滚
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
}
// 6. 只读事务
@Transactional(readOnly = true)
public List<User> getAllUsers() {
return userRepository.findAll();
}
// 7. 条件事务
@Transactional(rollbackFor = Exception.class, noRollbackFor = IllegalArgumentException.class)
public void createUserConditional(String name, String email) {
User user = new User();
user.setName(name);
user.setEmail(email);
userRepository.save(user);
// IllegalArgumentException不会导致回滚
if (email == null || !email.contains("@")) {
throw new IllegalArgumentException("邮箱格式不正确");
}
// 其他异常会导致回滚
if (name == null) {
throw new RuntimeException("用户名不能为空");
}
}
}
3.2 事务传播行为
@Service
public class TransactionPropagationService {
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
// 1. REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务
@Transactional(propagation = Propagation.REQUIRED)
public void createUserAndOrder(String userName, String orderName) {
// 创建用户
User user = new User();
user.setName(userName);
userRepository.save(user);
// 创建订单
Order order = new Order();
order.setUserId(user.getId());
order.setName(orderName);
orderRepository.save(order);
// 如果任何操作失败,整个事务都会回滚
}
// 2. REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则挂起当前事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUserInNewTransaction(String name) {
User user = new User();
user.setName(name);
userRepository.save(user);
// 这个操作在独立的事务中执行
// 即使外部事务回滚,这个操作也会提交
}
// 3. SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行
@Transactional(propagation = Propagation.SUPPORTS)
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
// 4. NOT_SUPPORTED:以非事务的方式执行,如果当前存在事务,则挂起当前事务
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void sendNotification(String message) {
// 发送通知,不参与事务
System.out.println("发送通知: " + message);
}
// 5. MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
@Transactional(propagation = Propagation.MANDATORY)
public void updateUserInTransaction(Long id, String name) {
User user = userRepository.findById(id).orElse(null);
if (user != null) {
user.setName(name);
userRepository.save(user);
}
// 这个方法必须在事务中调用
}
// 6. NEVER:以非事务的方式执行,如果当前存在事务,则抛出异常
@Transactional(propagation = Propagation.NEVER)
public void logOperation(String operation) {
// 记录操作日志,不能在事务中执行
System.out.println("记录操作: " + operation);
}
// 7. NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来执行
@Transactional(propagation = Propagation.NESTED)
public void createUserProfile(Long userId) {
UserProfile profile = new UserProfile();
profile.setUserId(userId);
profile.setCreatedAt(LocalDateTime.now());
// 这个操作在嵌套事务中执行
// 如果外部事务回滚,这个操作也会回滚
// 如果这个操作失败,外部事务可以选择回滚或继续
}
}
3.3 事务隔离级别
@Service
public class TransactionIsolationService {
@Autowired
private UserRepository userRepository;
@Autowired
private AccountRepository accountRepository;
// 1. READ_UNCOMMITTED:读未提交,最低隔离级别,允许脏读
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public User getUserWithDirtyRead(Long id) {
// 可能读取到未提交的数据
return userRepository.findById(id).orElse(null);
}
// 2. READ_COMMITTED:读已提交,防止脏读,但允许不可重复读
@Transactional(isolation = Isolation.READ_COMMITTED)
public User getUserWithReadCommitted(Long id) {
// 只能读取已提交的数据
return userRepository.findById(id).orElse(null);
}
// 3. REPEATABLE_READ:可重复读,防止不可重复读,但允许幻读
@Transactional(isolation = Isolation.REPEATABLE_READ)
public List<User> getUsersWithRepeatableRead() {
// 在事务期间,多次读取会得到相同的结果
return userRepository.findAll();
}
// 4. SERIALIZABLE:串行化,最高隔离级别,防止所有并发问题
@Transactional(isolation = Isolation.SERIALIZABLE)
public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
Account fromAccount = accountRepository.findById(fromAccountId).orElse(null);
Account toAccount = accountRepository.findById(toAccountId).orElse(null);
if (fromAccount != null && toAccount != null) {
if (fromAccount.getBalance().compareTo(amount) >= 0) {
fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
toAccount.setBalance(toAccount.getBalance().add(amount));
accountRepository.save(fromAccount);
accountRepository.save(toAccount);
} else {
throw new InsufficientFundsException("余额不足");
}
}
}
// 5. 默认隔离级别(通常是READ_COMMITTED)
@Transactional
public User getUserWithDefaultIsolation(Long id) {
return userRepository.findById(id).orElse(null);
}
}
4. 编程式事务管理
4.1 TransactionTemplate使用
@Service
public class TransactionTemplateService {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
// 1. 基本使用
public User createUserWithTemplate(String name, String email) {
return transactionTemplate.execute(status -> {
try {
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
User savedUser = userRepository.save(user);
// 创建用户档案
UserProfile profile = new UserProfile();
profile.setUserId(savedUser.getId());
profile.setCreatedAt(LocalDateTime.now());
return savedUser;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
});
}
// 2. 指定事务属性
public User createUserWithCustomTransaction(String name, String email) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setTimeout(30);
def.setReadOnly(false);
return transactionTemplate.execute(def, status -> {
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
return userRepository.save(user);
});
}
// 3. 异常处理
public User createUserWithExceptionHandling(String name, String email) {
return transactionTemplate.execute(status -> {
try {
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
User savedUser = userRepository.save(user);
// 模拟异常
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("用户名不能为空");
}
return savedUser;
} catch (IllegalArgumentException e) {
// 特定异常不回滚
status.setRollbackOnly();
throw e;
} catch (Exception e) {
// 其他异常回滚
status.setRollbackOnly();
throw e;
}
});
}
// 4. 嵌套事务
public void createUserAndOrder(String userName, String orderName) {
transactionTemplate.execute(status -> {
// 创建用户
User user = createUserInNestedTransaction(userName);
// 创建订单
Order order = new Order();
order.setUserId(user.getId());
order.setName(orderName);
orderRepository.save(order);
return null;
});
}
private User createUserInNestedTransaction(String name) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
return transactionTemplate.execute(def, status -> {
User user = new User();
user.setName(name);
user.setCreatedAt(LocalDateTime.now());
return userRepository.save(user);
});
}
}
4.2 PlatformTransactionManager使用
@Service
public class PlatformTransactionManagerService {
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private UserRepository userRepository;
// 1. 基本使用
public User createUserWithManager(String name, String email) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
User savedUser = userRepository.save(user);
// 提交事务
transactionManager.commit(status);
return savedUser;
} catch (Exception e) {
// 回滚事务
transactionManager.rollback(status);
throw e;
}
}
// 2. 复杂事务管理
public void complexTransactionOperation() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
def.setTimeout(60);
TransactionStatus status = transactionManager.getTransaction(def);
try {
// 第一步操作
performFirstOperation();
// 检查是否需要继续
if (shouldContinue()) {
// 第二步操作
performSecondOperation();
}
// 提交事务
transactionManager.commit(status);
} catch (Exception e) {
// 回滚事务
transactionManager.rollback(status);
throw e;
}
}
private void performFirstOperation() {
// 执行第一步操作
System.out.println("执行第一步操作");
}
private boolean shouldContinue() {
// 判断是否继续执行
return true;
}
private void performSecondOperation() {
// 执行第二步操作
System.out.println("执行第二步操作");
}
}
5. 事务事件和监听器
5.1 事务事件监听
@Component
public class TransactionEventListener {
private static final Logger logger = LoggerFactory.getLogger(TransactionEventListener.class);
// 1. 事务提交后事件
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleAfterCommit(TransactionEvent event) {
logger.info("事务提交后处理事件: {}", event.getMessage());
// 在事务提交后执行的操作
// 例如:发送通知、更新缓存等
sendNotification(event.getMessage());
updateCache(event.getData());
}
// 2. 事务回滚后事件
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void handleAfterRollback(TransactionEvent event) {
logger.info("事务回滚后处理事件: {}", event.getMessage());
// 在事务回滚后执行的操作
// 例如:记录失败日志、发送告警等
logFailure(event.getMessage());
sendAlert(event.getMessage());
}
// 3. 事务完成事件(无论提交还是回滚)
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
public void handleAfterCompletion(TransactionEvent event) {
logger.info("事务完成后处理事件: {}", event.getMessage());
// 在事务完成后执行的操作
// 例如:清理资源、更新统计信息等
cleanupResources();
updateStatistics();
}
private void sendNotification(String message) {
// 发送通知
System.out.println("发送通知: " + message);
}
private void updateCache(Object data) {
// 更新缓存
System.out.println("更新缓存: " + data);
}
private void logFailure(String message) {
// 记录失败日志
System.err.println("记录失败: " + message);
}
private void sendAlert(String message) {
// 发送告警
System.err.println("发送告警: " + message);
}
private void cleanupResources() {
// 清理资源
System.out.println("清理资源");
}
private void updateStatistics() {
// 更新统计信息
System.out.println("更新统计信息");
}
}
// 事务事件类
public class TransactionEvent {
private final String message;
private final Object data;
private final LocalDateTime timestamp;
public TransactionEvent(String message, Object data) {
this.message = message;
this.data = data;
this.timestamp = LocalDateTime.now();
}
// getter方法
public String getMessage() { return message; }
public Object getData() { return data; }
public LocalDateTime getTimestamp() { return timestamp; }
}
5.2 事务同步
@Service
public class TransactionSynchronizationService {
@Autowired
private UserRepository userRepository;
// 1. 事务同步
@Transactional
public void createUserWithSynchronization(String name, String email) {
// 注册事务同步
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void beforeCommit(boolean readOnly) {
System.out.println("事务提交前执行");
}
@Override
public void beforeCompletion() {
System.out.println("事务完成前执行");
}
@Override
public void afterCommit() {
System.out.println("事务提交后执行");
// 在这里可以安全地执行事务提交后的操作
sendNotification(name, email);
}
@Override
public void afterCompletion(int status) {
System.out.println("事务完成后执行,状态: " + status);
// 在这里可以执行清理操作
cleanupResources();
}
});
// 执行业务逻辑
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
userRepository.save(user);
}
// 2. 资源绑定
@Transactional
public void createUserWithResourceBinding(String name, String email) {
// 绑定资源到当前事务
String resourceKey = "userCreation";
Object resource = new Object();
TransactionSynchronizationManager.bindResource(resourceKey, resource);
try {
// 执行业务逻辑
User user = new User();
user.setName(name);
user.setEmail(email);
user.setCreatedAt(LocalDateTime.now());
userRepository.save(user);
// 获取绑定的资源
Object boundResource = TransactionSynchronizationManager.getResource(resourceKey);
System.out.println("绑定的资源: " + boundResource);
} finally {
// 解绑资源
TransactionSynchronizationManager.unbindResource(resourceKey);
}
}
private void sendNotification(String name, String email) {
// 发送通知
System.out.println("发送用户创建通知: " + name + ", " + email);
}
private void cleanupResources() {
// 清理资源
System.out.println("清理资源");
}
}
6. 分布式事务管理
6.1 JTA事务管理
@Configuration
public class JtaTransactionConfig {
@Bean
public JtaTransactionManager jtaTransactionManager() {
JtaTransactionManager transactionManager = new JtaTransactionManager();
// 配置JTA事务管理器
transactionManager.setTransactionManagerName("java:/TransactionManager");
transactionManager.setUserTransactionName("java:jboss/UserTransaction");
return transactionManager;
}
@Bean
public AtomikosDataSourceBean dataSource1() {
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
dataSource.setUniqueResourceName("dataSource1");
dataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
Properties props = new Properties();
props.setProperty("url", "jdbc:mysql://localhost:3306/db1");
props.setProperty("user", "user1");
props.setProperty("password", "password1");
dataSource.setXaProperties(props);
return dataSource;
}
@Bean
public AtomikosDataSourceBean dataSource2() {
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
dataSource.setUniqueResourceName("dataSource2");
dataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
Properties props = new Properties();
props.setProperty("url", "jdbc:mysql://localhost:3306/db2");
props.setProperty("user", "user2");
props.setProperty("password", "password2");
dataSource.setXaProperties(props);
return dataSource;
}
}
@Service
public class DistributedTransactionService {
@Autowired
private JdbcTemplate jdbcTemplate1;
@Autowired
private JdbcTemplate jdbcTemplate2;
// 分布式事务操作
@Transactional
public void performDistributedOperation() {
// 在第一个数据源上执行操作
jdbcTemplate1.execute("INSERT INTO users (name, email) VALUES (?, ?)",
"User1", "user1@example.com");
// 在第二个数据源上执行操作
jdbcTemplate2.execute("INSERT INTO orders (user_id, amount) VALUES (?, ?)",
1L, 100.0);
// 如果任何操作失败,整个分布式事务都会回滚
}
}
6.2 链式事务管理器
@Configuration
public class ChainedTransactionConfig {
@Bean
public ChainedTransactionManager chainedTransactionManager(
DataSourceTransactionManager dataSourceTransactionManager,
JpaTransactionManager jpaTransactionManager) {
return new ChainedTransactionManager(dataSourceTransactionManager, jpaTransactionManager);
}
}
@Service
public class ChainedTransactionService {
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
// 链式事务操作
@Transactional
public void performChainedOperation() {
// 在JPA事务中创建用户
User user = new User();
user.setName("John Doe");
user.setEmail("john@example.com");
userRepository.save(user);
// 在JDBC事务中创建订单
jdbcTemplate.execute("INSERT INTO orders (user_id, amount) VALUES (?, ?)",
user.getId(), 200.0);
// 如果任何操作失败,所有事务都会回滚
}
}
7. 事务最佳实践
7.1 事务设计原则
@Service
public class TransactionDesignService {
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
// 1. 事务边界要合理
@Transactional
public void createUserAndOrder(String userName, String orderName) {
// 创建用户和订单是业务上相关的操作,应该在一个事务中
User user = createUser(userName);
createOrder(user.getId(), orderName);
}
// 2. 避免长事务
@Transactional
public void processLargeBatch(List<String> userNames) {
// 分批处理,避免长事务
int batchSize = 100;
for (int i = 0; i < userNames.size(); i += batchSize) {
int endIndex = Math.min(i + batchSize, userNames.size());
List<String> batch = userNames.subList(i, endIndex);
processBatch(batch);
}
}
// 3. 合理使用事务传播行为
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logOperation(String operation) {
// 日志记录使用独立事务,避免影响主业务事务
System.out.println("记录操作: " + operation);
}
// 4. 异常处理要明确
@Transactional(rollbackFor = {SQLException.class, DataIntegrityViolationException.class})
public void createUserWithClearRollback(String name, String email) {
try {
User user = new User();
user.setName(name);
user.setEmail(email);
userRepository.save(user);
} catch (SQLException e) {
// 明确指定回滚
throw new RuntimeException("数据库操作失败", e);
}
}
private User createUser(String name) {
User user = new User();
user.setName(name);
user.setCreatedAt(LocalDateTime.now());
return userRepository.save(user);
}
private void createOrder(Long userId, String orderName) {
Order order = new Order();
order.setUserId(userId);
order.setName(orderName);
order.setCreatedAt(LocalDateTime.now());
orderRepository.save(order);
}
private void processBatch(List<String> userNames) {
for (String name : userNames) {
createUser(name);
}
}
}
7.2 事务性能优化
@Service
public class TransactionPerformanceService {
@Autowired
private UserRepository userRepository;
// 1. 使用只读事务
@Transactional(readOnly = true)
public List<User> getAllUsers() {
// 只读操作使用只读事务,提高性能
return userRepository.findAll();
}
// 2. 合理设置超时时间
@Transactional(timeout = 10)
public void quickOperation() {
// 快速操作设置较短的超时时间
System.out.println("执行快速操作");
}
// 3. 批量操作优化
@Transactional
public void batchInsertUsers(List<User> users) {
// 使用批量插入提高性能
userRepository.saveAll(users);
}
// 4. 避免在事务中执行耗时操作
@Transactional
public void createUserWithAsyncNotification(String name, String email) {
// 创建用户
User user = new User();
user.setName(name);
user.setEmail(email);
userRepository.save(user);
// 异步发送通知,避免阻塞事务
CompletableFuture.runAsync(() -> {
sendNotification(name, email);
});
}
private void sendNotification(String name, String email) {
// 发送通知的耗时操作
try {
Thread.sleep(1000);
System.out.println("发送通知: " + name + ", " + email);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
7.3 事务监控和调试
@Component
public class TransactionMonitor {
private static final Logger logger = LoggerFactory.getLogger(TransactionMonitor.class);
// 1. 事务开始监控
@EventListener
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void monitorTransactionStart(TransactionEvent event) {
logger.info("事务开始: {}", event.getMessage());
// 记录事务开始时间
TransactionSynchronizationManager.bindResource("startTime", System.currentTimeMillis());
}
// 2. 事务提交监控
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void monitorTransactionCommit(TransactionEvent event) {
logger.info("事务提交: {}", event.getMessage());
// 计算事务执行时间
Long startTime = (Long) TransactionSynchronizationManager.getResource("startTime");
if (startTime != null) {
long duration = System.currentTimeMillis() - startTime;
logger.info("事务执行时间: {}ms", duration);
// 记录性能指标
recordPerformanceMetrics(duration);
}
}
// 3. 事务回滚监控
@EventListener
@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
public void monitorTransactionRollback(TransactionEvent event) {
logger.warn("事务回滚: {}", event.getMessage());
// 记录回滚原因
recordRollbackReason(event.getMessage());
}
// 4. 事务统计信息
private final AtomicLong totalTransactions = new AtomicLong(0);
private final AtomicLong committedTransactions = new AtomicLong(0);
private final AtomicLong rolledBackTransactions = new AtomicLong(0);
public Map<String, Long> getTransactionStats() {
Map<String, Long> stats = new HashMap<>();
stats.put("total", totalTransactions.get());
stats.put("committed", committedTransactions.get());
stats.put("rolledBack", rolledBackTransactions.get());
return stats;
}
private void recordPerformanceMetrics(long duration) {
// 记录性能指标
if (duration > 1000) {
logger.warn("长事务警告: {}ms", duration);
}
}
private void recordRollbackReason(String reason) {
// 记录回滚原因
logger.error("事务回滚原因: {}", reason);
}
}
总结
ApplicationContext在事务管理方面相比BeanFactory提供了以下重要扩展,其核心特性如下:
- 事务传播行为:REQUIRED、REQUIRES_NEW、SUPPORTS、NOT_SUPPORTED、MANDATORY、NEVER、NESTED
- 事务隔离级别:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE
- 事务超时设置:控制事务执行的最大时间
- 回滚策略:指定哪些异常会导致事务回滚
- 只读事务:优化只读操作的性能