本文目录导读:

在Java中声明事务通常有两种主流方式:注解方式(推荐)和XML配置方式,下面我按照Spring Boot + Spring Data JPA和传统Spring XML两种场景,给你完整的配置案例。
Spring Boot 注解方式(最常用)
Spring Boot 只要引入了相关依赖,事务基本是“开箱即用”的,但需要显式开启事务管理。
添加依赖(pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
配置数据源和JPA(application.yml)
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: update
show-sql: true
database-platform: org.hibernate.dialect.H2Dialect
开启事务管理(Application主类)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement // 显式开启事务管理(Spring Boot 会自动配置,但显式写出来更清晰)
public class TransactionDemoApplication {
public static void main(String[] args) {
SpringApplication.run(TransactionDemoApplication.class, args);
}
}
注意:
@EnableTransactionManagement在 Spring Boot 中不是必须的,它默认已经自动配置了,但如果你需要自定义事务管理器,则需要显式使用。
实体类(User.java)
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
// getters and setters 省略
}
Repository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Service 层使用 @Transactional
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// 方法级别:这个方法内所有数据库操作在同一个事务中
@Transactional
public void transferMoney(Long fromUserId, Long toUserId, Integer amount) {
User from = userRepository.findById(fromUserId).orElseThrow();
User to = userRepository.findById(toUserId).orElseThrow();
from.setAge(from.getAge() - amount); // 模拟扣钱
to.setAge(to.getAge() + amount); // 模拟加钱
userRepository.save(from);
userRepository.save(to);
// 如果这里抛出异常,上述两个操作都会回滚
}
// 类级别:整个类的所有public方法都默认有事务
@Transactional(readOnly = true) // 只读事务,提高性能
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
Controller 调用验证
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/transfer")
public String transfer(@RequestParam Long from, @RequestParam Long to, @RequestParam Integer amount) {
try {
userService.transferMoney(from, to, amount);
return "转账成功";
} catch (Exception e) {
return "转账失败: " + e.getMessage();
}
}
}
传统 Spring XML 配置方式
如果你还在使用传统的 Spring XML 配置项目,配置如下:
配置数据源、事务管理器(applicationContext.xml)
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 1. 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<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"/>
</bean>
<!-- 2. JPA 实体管理工厂 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.example.entity"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 3. 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- 4. 开启注解事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
Service 层使用注解(同 Spring Boot 方式)
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void transferMoney(Long fromId, Long toId, Integer amount) {
// ... 业务逻辑
}
}
@Transactional 重要参数说明
| 参数 | 说明 | 默认值 |
|---|---|---|
| propagation | 事务传播行为 | Propagation.REQUIRED |
| isolation | 事务隔离级别 | Isolation.DEFAULT |
| timeout | 超时时间(秒) | -1(不超时) |
| readOnly | 是否只读事务 | false |
| rollbackFor | 指定哪些异常触发回滚 | 运行时异常(RuntimeException) |
| noRollbackFor | 指定哪些异常不触发回滚 | 空 |
示例:
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 30,
rollbackFor = {Exception.class},
readOnly = false
)
public void someMethod() {
// ...
}
常见注意事项
- @Transactional 只能用在 public 方法上,private 或 protected 无效。
- 自身调用失效:同一个类中方法 A(无事务)调用方法 B(有事务),B 的事务不会生效(需要注入代理对象)。
- 异常回滚:默认只对 RuntimeException 和 Error 回滚,如果希望 checked exception 也回滚,需要设置
rollbackFor = Exception.class。 - 只读事务:查询操作建议设置
readOnly = true,可以提高性能。
如果你有具体的框架(如 Spring Cloud、MyBatis)或场景(如分布式事务)需求,可以进一步补充,我可以给你更针对性的配置。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播