# Spring中怎么使用注解聲明事務
## 1. 事務管理概述
在Spring框架中,事務管理是核心功能之一。Spring提供了兩種事務管理方式:
- **編程式事務**:通過編寫代碼手動管理事務
- **聲明式事務**:通過配置(XML或注解)聲明事務行為
其中**基于注解的聲明式事務**因其簡潔性和易用性成為最常用的方式。
## 2. 基礎環境配置
### 2.1 添加依賴
```xml
<!-- Spring事務核心依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.18</version>
</dependency>
<!-- 數據庫相關 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.18</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
</dependency>
@Configuration
@EnableTransactionManagement // 啟用注解驅動的事務管理
public class AppConfig {
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("root");
ds.setPassword("password");
return ds;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
在方法或類上添加@Transactional
注解即可聲明事務:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional
@Override
public void createUser(User user) {
userDao.insert(user);
}
}
屬性名 | 說明 | 默認值 |
---|---|---|
propagation | 事務傳播行為 | REQUIRED |
isolation | 事務隔離級別 | DEFAULT |
timeout | 事務超時時間(秒) | -1(不超時) |
readOnly | 是否只讀事務 | false |
rollbackFor | 觸發回滾的異常類型 | {} |
noRollbackFor | 不觸發回滾的異常類型 | {} |
示例:
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 30,
rollbackFor = {SQLException.class},
noRollbackFor = {NullPointerException.class}
)
public void transferMoney(Long from, Long to, BigDecimal amount) {
// 業務邏輯
}
Spring定義了7種傳播行為:
傳播行為類型 | 說明 |
---|---|
REQUIRED | 如果當前存在事務,則加入該事務;否則新建事務 |
SUPPORTS | 如果當前存在事務,則加入該事務;否則以非事務方式運行 |
MANDATORY | 必須在一個已有的事務中執行,否則拋出異常 |
REQUIRES_NEW | 新建事務,如果當前存在事務則掛起 |
NOT_SUPPORTED | 以非事務方式執行,如果當前存在事務則掛起 |
NEVER | 以非事務方式執行,如果當前存在事務則拋出異常 |
NESTED | 如果當前存在事務,則在嵌套事務內執行 |
示例:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logOperation(OperationLog log) {
// 記錄操作日志,需要獨立事務
}
Spring支持的標準隔離級別:
隔離級別 | 說明 |
---|---|
DEFAULT | 使用底層數據庫默認隔離級別 |
READ_UNCOMMITTED | 讀未提交 |
READ_COMMITTED | 讀已提交 |
REPEATABLE_READ | 可重復讀 |
SERIALIZABLE | 串行化 |
示例:
@Transactional(isolation = Isolation.READ_COMMITTED)
public User getUserWithBalance(Long userId) {
// 需要讀取已提交的數據
}
注解位置:
異常處理:
rollbackFor
自調用問題:
public class OrderService {
public void placeOrder(Order order) {
validateOrder(order); // 這里的事務注解不會生效
processPayment();
}
@Transactional
public void validateOrder(Order order) {
// 驗證邏輯
}
}
解決方法:
性能考慮:
@Configuration
@EnableTransactionManagement
public class MultiDataSourceConfig {
@Bean
@Primary
public PlatformTransactionManager primaryTxManager(DataSource ds1) {
return new DataSourceTransactionManager(ds1);
}
@Bean
public PlatformTransactionManager secondaryTxManager(DataSource ds2) {
return new DataSourceTransactionManager(ds2);
}
}
// 使用指定的事務管理器
@Service
public class CrossDbService {
@Transactional("primaryTxManager")
public void primaryDbOp() {...}
@Transactional("secondaryTxManager")
public void secondaryDbOp() {...}
}
@SpringBootApplication
@EnableTransactionManagement
@MapperScan("com.example.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
事務不生效:
@EnableTransactionManagement
長事務問題:
連接泄露:
通過合理使用@Transactional
注解,可以大大簡化Spring應用中的事務管理,同時保持代碼的清晰性和可維護性。
“`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。