springboot项目 事务的隔离政策 介绍 及 如何选择,请给出全面且详尽的示例和介绍,为什么不建议用@transactionl,建议用什么呢
时间: 2024-02-15 16:06:01 浏览: 74
在Spring Boot中,事务管理是非常重要的一部分,它可以确保在数据库操作中出现异常时,数据库的一致性不会被破坏。一个事务可以包含多个操作,这些操作要么全部成功,要么全部失败。
Spring Boot中的事务隔离级别定义了多个连接之间事务的隔离程度。在事务隔离级别较高的情况下,一个事务的操作不会被其他事务的操作所干扰。Spring Boot中提供了四个事务隔离级别,分别是:
1. 读未提交(READ_UNCOMMITTED):该隔离级别允许脏读、不可重复读和幻读,即一个事务可以读取另一个事务未提交的数据。
2. 读已提交(READ_COMMITTED):该隔离级别允许不可重复读和幻读,但阻止脏读,即一个事务只能读取另一个事务已提交的数据。
3. 可重复读(REPEATABLE_READ):该隔离级别允许防止脏读和不可重复读,但是可能出现幻读,即一个事务不会读取另一个事务已提交的新增数据,但是可能读取另一个事务未提交的新增数据。
4. 串行化(SERIALIZABLE):该隔离级别提供最高的事务隔离级别,防止脏读、不可重复读和幻读,但是会降低并发性能。
选择哪个隔离级别取决于应用程序的需求。如果需要最高的数据一致性,可以选择串行化隔离级别,但是需要注意并发性能的影响。如果不需要最高的一致性,可以选择较低的隔离级别。
在Spring Boot中,我们可以使用@Transactional注解来声明一个事务。@Transactional注解可以应用于方法级别和类级别,用于指定事务的隔离级别、传播特性、超时时间、只读属性等。但是,建议不要在Service层使用@Transactional注解。因为在Service层使用@Transactional注解会引起一些问题,例如:
1. Service层的代码可能会被多次调用,这样可能会导致事务被多次开启和提交,从而引发数据一致性问题。
2. Service层的代码可能会被其他模块调用,这样可能会引发事务传播的问题,从而影响数据一致性。
因此,建议在DAO层使用@Transactional注解,而不是在Service层使用。在DAO层使用@Transactional注解可以确保DAO层的所有操作都在一个事务中执行,从而保证数据一致性。
示例代码如下所示:
```java
@Repository
@Transactional(rollbackFor = Exception.class)
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public void save(User user) {
String sql = "insert into user (name, age) values (?, ?)";
Object[] params = new Object[] {user.getName(), user.getAge()};
jdbcTemplate.update(sql, params);
}
@Override
public void update(User user) {
String sql = "update user set age = ? where name = ?";
Object[] params = new Object[] {user.getAge(), user.getName()};
jdbcTemplate.update(sql, params);
}
@Override
public void delete(String name) {
String sql = "delete from user where name = ?";
Object[] params = new Object[] {name};
jdbcTemplate.update(sql, params);
}
@Override
public User findByName(String name) {
String sql = "select name, age from user where name = ?";
Object[] params = new Object[] {name};
RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
List<User> list = jdbcTemplate.query(sql, params, rowMapper);
return list.isEmpty() ? null : list.get(0);
}
}
```
在上面的示例代码中,我们在UserDaoImpl类上添加了@Transactional注解,并指定了rollbackFor属性。这样可以确保在发生异常时,事务会回滚。
另外,建议在DAO层使用Spring Boot提供的事务模板TransactionTemplate来管理事务。使用TransactionTemplate可以更加灵活地控制事务的隔离级别、传播特性、超时时间等属性。
示例代码如下所示:
```java
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private TransactionTemplate transactionTemplate;
@Override
public void save(User user) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
String sql = "insert into user (name, age) values (?, ?)";
Object[] params = new Object[] {user.getName(), user.getAge()};
jdbcTemplate.update(sql, params);
}
});
}
@Override
public void update(User user) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
String sql = "update user set age = ? where name = ?";
Object[] params = new Object[] {user.getAge(), user.getName()};
jdbcTemplate.update(sql, params);
}
});
}
@Override
public void delete(String name) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
String sql = "delete from user where name = ?";
Object[] params = new Object[] {name};
jdbcTemplate.update(sql, params);
}
});
}
@Override
public User findByName(String name) {
String sql = "select name, age from user where name = ?";
Object[] params = new Object[] {name};
RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class);
List<User> list = jdbcTemplate.query(sql, params, rowMapper);
return list.isEmpty() ? null : list.get(0);
}
}
```
在上面的示例代码中,我们使用了TransactionTemplate来管理事务。在TransactionTemplate的execute方法中,我们可以执行需要在事务中执行的操作。同时,我们还可以设置事务的隔离级别、传播特性、超时时间等属性。
总之,在Spring Boot中,事务管理是非常重要的一部分,我们应该根据应用程序的需求选择合适的事务隔离级别,并在DAO层使用@Transactional注解或者TransactionTemplate来管理事务。同时,不建议在Service层使用@Transactional注解。
阅读全文